PS2SDK
PS2 Homebrew Libraries
Loading...
Searching...
No Matches
dvrfile.c
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright 2021-2021, 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
11#include "iomanX.h"
12#include "loadcore.h"
13#include "pvrdrv.h"
14#include "stdio.h"
15#include "sysclib.h"
16#include "thbase.h"
17#include "thsemap.h"
18#include "speedregs.h"
19#include "errno.h"
20
21#define MODNAME "DVRFILE"
22#ifdef DEBUG
23#define DPRINTF(x...) printf(MODNAME ": " x)
24#else
25#define DPRINTF(x...)
26#endif
27
28extern int module_start(int argc, char *argv[], void *startaddr, ModuleInfo_t *mi);
29extern int module_stop(int argc, char *argv[], void *startaddr, ModuleInfo_t *mi);
30extern int dvrf_df_init(iomanX_iop_device_t *f);
31extern int dvrf_df_exit(iomanX_iop_device_t *f);
32extern int dvrf_df_chdir(iomanX_iop_file_t *f, const char *name);
33extern int dvrf_df_chstat(iomanX_iop_file_t *f, const char *name, iox_stat_t *stat, unsigned int statmask);
34extern int dvrf_df_close(iomanX_iop_file_t *f);
35extern int dvrf_df_dclose(iomanX_iop_file_t *f);
36extern int dvrf_df_devctl(iomanX_iop_file_t *f, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
37extern int dvrf_df_dopen(iomanX_iop_file_t *f, const char *path);
38extern int dvrf_df_dread(iomanX_iop_file_t *f, iox_dirent_t *buf);
39extern int dvrf_df_format(iomanX_iop_file_t *f, const char *dev, const char *blockdev, void *arg, int arglen);
40extern int dvrf_df_getstat(iomanX_iop_file_t *f, const char *name, iox_stat_t *stat);
41extern int dvrf_df_ioctl(iomanX_iop_file_t *f, int cmd, void *param);
42extern int dvrf_df_ioctl2(iomanX_iop_file_t *f, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen);
43extern int dvrf_df_lseek(iomanX_iop_file_t *f, int offset, int mode);
44extern s64 dvrf_df_lseek64(iomanX_iop_file_t *f, s64 offset, int whence);
45extern int dvrf_df_mkdir(iomanX_iop_file_t *f, const char *path, int mode);
46extern int dvrf_df_mount(iomanX_iop_file_t *f, const char *fsname, const char *devname, int flag, void *arg, int arglen);
47extern int dvrf_df_open(iomanX_iop_file_t *f, const char *name, int flags, int mode);
48extern int dvrf_df_read(iomanX_iop_file_t *f, void *ptr, int size);
49extern int dvrf_df_readlink(iomanX_iop_file_t *f, const char *path, char *buf, unsigned int buflen);
50extern int dvrf_df_remove(iomanX_iop_file_t *f, const char *name);
51extern int dvrf_df_rename(iomanX_iop_file_t *f, const char *old, const char *new_1);
52extern int dvrf_df_rmdir(iomanX_iop_file_t *f, const char *path);
53extern int dvrf_df_symlink(iomanX_iop_file_t *f, const char *old, const char *new_1);
54extern int dvrf_df_sync(iomanX_iop_file_t *f, const char *dev, int flag);
55extern int dvrf_df_umount(iomanX_iop_file_t *f, const char *fsname);
56extern int dvrf_df_write(iomanX_iop_file_t *f, void *ptr, int size);
57extern void CopySceStat(iox_stat_t *stat, u8 *dvrp_stat);
58
59static inline u32 bswap32(u32 val)
60{
61#if 0
62 return __builtin_bswap32(val);
63#else
64 return (val << 24) + ((val & 0xFF00) << 8) + ((val >> 8) & 0xFF00) + ((val >> 24) & 0xFF);
65#endif
66}
67
68static int dvrf_translator_df_chdir(iomanX_iop_file_t *f, const char *name)
69{
70 char translated_name[1040];
71
72 sprintf(translated_name, "%s%d:%s", f->device->name, f->unit, name);
73 return dvrf_df_chdir(f, translated_name);
74}
75
76static int dvrf_translator_df_chstat(iomanX_iop_file_t *f, const char *name, iox_stat_t *stat, unsigned int statmask)
77{
78 char translated_name[1040];
79
80 sprintf(translated_name, "%s%d:%s", f->device->name, f->unit, name);
81 return dvrf_df_chstat(f, translated_name, stat, statmask);
82}
83
84static int dvrf_translator_df_devctl(iomanX_iop_file_t *f, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen)
85{
86 char translated_name[1040];
87
88 sprintf(translated_name, "%s%d:%s", f->device->name, f->unit, name);
89 return dvrf_df_devctl(f, translated_name, cmd, arg, arglen, buf, buflen);
90}
91
92static int dvrf_translator_df_dopen(iomanX_iop_file_t *f, const char *path)
93{
94 char translated_path[1040];
95
96 sprintf(translated_path, "%s%d:%s", f->device->name, f->unit, path);
97 return dvrf_df_dopen(f, translated_path);
98}
99
100static int dvrf_translator_df_format(iomanX_iop_file_t *f, const char *dev, const char *blockdev, void *arg, int arglen)
101{
102 char translated_dev[1040];
103
104 if (strcmp(f->device->name, "dvr_hdd") != 0) {
105 sprintf(translated_dev, "%s:%s", f->device->name, dev);
106 *(u32 *)arg = bswap32(*(u32 *)arg);
107 } else {
108 sprintf(translated_dev, "%s%d:%s", f->device->name, f->unit, dev);
109 }
110 return dvrf_df_format(f, translated_dev, blockdev, arg, arglen);
111}
112
113static int dvrf_translator_df_getstat(iomanX_iop_file_t *f, const char *name, iox_stat_t *stat)
114{
115 char translated_name[1040];
116
117 sprintf(translated_name, "%s%d:%s", f->device->name, f->unit, name);
118 return dvrf_df_getstat(f, translated_name, stat);
119}
120
121static int dvrf_translator_df_mkdir(iomanX_iop_file_t *f, const char *path, int mode)
122{
123 char translated_path[1040];
124
125 sprintf(translated_path, "%s%d:%s", f->device->name, f->unit, path);
126 return dvrf_df_mkdir(f, translated_path, mode);
127}
128
129static int dvrf_translator_df_mount(iomanX_iop_file_t *f, const char *fsname, const char *devname, int flag, void *arg, int arglen)
130{
131 char translated_fsname[1040];
132
133 sprintf(translated_fsname, "%s%d:%s", f->device->name, f->unit, fsname);
134 return dvrf_df_mount(f, translated_fsname, devname, flag, arg, arglen);
135}
136
137static int dvrf_translator_df_open(iomanX_iop_file_t *f, const char *name, int flags, int mode)
138{
139 char translated_name[1040];
140
141 sprintf(translated_name, "%s%d:%s", f->device->name, f->unit, name);
142 return dvrf_df_open(f, translated_name, flags, mode);
143}
144
145static int dvrf_translator_df_readlink(iomanX_iop_file_t *f, const char *path, char *buf, unsigned int buflen)
146{
147 char translated_path[1040];
148
149 sprintf(translated_path, "%s%d:%s", f->device->name, f->unit, path);
150 return dvrf_df_readlink(f, translated_path, buf, buflen);
151}
152
153static int dvrf_translator_df_remove(iomanX_iop_file_t *f, const char *name)
154{
155 char translated_name[1040];
156
157 sprintf(translated_name, "%s%d:%s", f->device->name, f->unit, name);
158 return dvrf_df_remove(f, translated_name);
159}
160
161static int dvrf_translator_df_rename(iomanX_iop_file_t *f, const char *old, const char *new_1)
162{
163 char translated_old[1040];
164 char translated_new[1040];
165
166 sprintf(translated_old, "%s%d:%s", f->device->name, f->unit, old);
167 sprintf(translated_new, "%s%d:%s", f->device->name, f->unit, new_1);
168 return dvrf_df_rename(f, translated_old, translated_new);
169}
170
171static int dvrf_translator_df_rmdir(iomanX_iop_file_t *f, const char *path)
172{
173 char translated_path[1040];
174
175 sprintf(translated_path, "%s%d:%s", f->device->name, f->unit, path);
176 return dvrf_df_rmdir(f, translated_path);
177}
178
179static int dvrf_translator_df_symlink(iomanX_iop_file_t *f, const char *old, const char *new_1)
180{
181 char translated_old[1040];
182 char translated_new[1040];
183
184 sprintf(translated_old, "%s%d:%s", f->device->name, f->unit, old);
185 sprintf(translated_new, "%s%d:%s", f->device->name, f->unit, new_1);
186 return dvrf_df_symlink(f, translated_old, translated_new);
187}
188
189static int dvrf_translator_df_sync(iomanX_iop_file_t *f, const char *dev, int flag)
190{
191 char translated_dev[1040];
192
193 sprintf(translated_dev, "%s%d:%s", f->device->name, f->unit, dev);
194 return dvrf_df_sync(f, translated_dev, flag);
195}
196
197static int dvrf_translator_df_umount(iomanX_iop_file_t *f, const char *fsname)
198{
199 char translated_fsname[1040];
200
201 sprintf(translated_fsname, "%s%d:%s", f->device->name, f->unit, fsname);
202 return dvrf_df_umount(f, translated_fsname);
203}
204
205static iomanX_iop_device_ops_t dvrf_translator_functbl = {
206 dvrf_df_init, // init
207 dvrf_df_exit, // deinit
208 dvrf_translator_df_format, // format
209 dvrf_translator_df_open, // open
210 dvrf_df_close, // close
211 dvrf_df_read, // read
212 dvrf_df_write, // write
213 dvrf_df_lseek, // lseek
214 dvrf_df_ioctl, // ioctl
215 dvrf_translator_df_remove, // remove
216 dvrf_translator_df_mkdir, // mkdir
217 dvrf_translator_df_rmdir, // rmdir
218 dvrf_translator_df_dopen, // dopen
219 dvrf_df_dclose, // dclose
220 dvrf_df_dread, // dread
221 dvrf_translator_df_getstat, // getstat
222 dvrf_translator_df_chstat, // chstat
223 dvrf_translator_df_rename, // rename
224 dvrf_translator_df_chdir, // chdir
225 dvrf_translator_df_sync, // sync
226 dvrf_translator_df_mount, // mount
227 dvrf_translator_df_umount, // umount
228 dvrf_df_lseek64, // lseek64
229 dvrf_translator_df_devctl, // devctl
230 dvrf_translator_df_symlink, // symlink
231 dvrf_translator_df_readlink, // readlink
232 dvrf_df_ioctl2, // ioctl2
233};
234
235#define GEN_TRANSLATION_FUNCS(basefuncname, basedevname, shouldbswapformatarg, drvname) \
236 static iomanX_iop_device_t basefuncname##_drv = { \
237 basedevname, \
238 (IOP_DT_FS | IOP_DT_FSEXT), \
239 1, \
240 drvname, \
241 &dvrf_translator_functbl, \
242 };
243
244GEN_TRANSLATION_FUNCS(dvrpfs, "dvr_pfs", 1, "PFS Driver for DVR");
245GEN_TRANSLATION_FUNCS(dvrhdd, "dvr_hdd", 0, "HDD Driver for DVR");
246GEN_TRANSLATION_FUNCS(dvrhdck, "dvr_hdck", 1, "HDCK Driver for DVR");
247GEN_TRANSLATION_FUNCS(dvrfssk, "dvr_fssk", 1, "FSSK Driver for DVR");
248GEN_TRANSLATION_FUNCS(dvrfsck, "dvr_fsck", 1, "FSCK Driver for DVR");
249
250s32 sema_id;
251int current_chunk_size;
252int RBUF[32768];
253int SBUF[32768];
254
255// Based off of DESR / PSX DVR system software version 1.31.
256IRX_ID(MODNAME, 1, 1);
257
258int _start(int argc, char *argv[], void *startaddr, ModuleInfo_t *mi)
259{
260 if (argc >= 0)
261 return module_start(argc, argv, startaddr, mi);
262 else
263 return module_stop(argc, argv, startaddr, mi);
264}
265
266int module_start(int argc, char *argv[], void *startaddr, ModuleInfo_t *mi)
267{
268 int i;
269 USE_SPD_REGS;
270
271 (void)startaddr;
272
273 for (i = 0; i < 30000; i += 1) {
274 if ((SPD_REG16(0x4230) & 0x20) != 0) {
275 break;
276 }
277 DelayThread(1000);
278 }
279
280 if (i == 30000) {
281 DPRINTF("IOMAN task of DVRP is not running...\n");
282 return MODULE_NO_RESIDENT_END;
283 }
284 sema_id = -1;
285 current_chunk_size = 0x4000;
286 if (iomanX_AddDrv(&dvrpfs_drv) || iomanX_AddDrv(&dvrhdd_drv)) {
287 goto fail;
288 }
289 for (i = 0; i < argc; i += 1) {
290 if (!strcmp(argv[i], "fschk"))
291 goto setup_fschk;
292 }
293#if 0
294 return MODULE_REMOVABLE_END;
295#else
296 if (mi && ((mi->newflags & 2) != 0))
297 mi->newflags |= 0x10;
298 return MODULE_RESIDENT_END;
299#endif
300setup_fschk:
301 DPRINTF("dvrfile.irx : FILE SYSTEM CHECK MODE\n");
302
303 if (iomanX_AddDrv(&dvrhdck_drv)) {
304 DPRINTF("hdck\n");
305 goto fail;
306 }
307 if (iomanX_AddDrv(&dvrfssk_drv)) {
308 DPRINTF("fssk\n");
309 goto fail;
310 }
311 if (iomanX_AddDrv(&dvrfsck_drv)) {
312 DPRINTF("fsck\n");
313 goto fail;
314 }
315#if 0
316 return MODULE_REMOVABLE_END;
317#else
318 if (mi && ((mi->newflags & 2) != 0))
319 mi->newflags |= 0x10;
320 return MODULE_RESIDENT_END;
321#endif
322fail:
323 iomanX_DelDrv(dvrpfs_drv.name);
324 iomanX_DelDrv(dvrhdd_drv.name);
325 iomanX_DelDrv(dvrhdck_drv.name);
326 iomanX_DelDrv(dvrfssk_drv.name);
327 iomanX_DelDrv(dvrfsck_drv.name);
328 return MODULE_NO_RESIDENT_END;
329}
330
331int module_stop(int argc, char *argv[], void *startaddr, ModuleInfo_t *mi)
332{
333 (void)argc;
334 (void)argv;
335 (void)startaddr;
336 (void)mi;
337
338
339 if (iomanX_DelDrv(dvrpfs_drv.name) || iomanX_DelDrv(dvrhdd_drv.name)) {
340#if 0
341 return MODULE_REMOVABLE_END;
342#else
343 return MODULE_RESIDENT_END;
344#endif
345 }
346 return MODULE_NO_RESIDENT_END;
347}
348
349static int check_cmdack_err(int (*func)(drvdrv_exec_cmd_ack *cmdack), drvdrv_exec_cmd_ack *cmdack, int *retval, const char *funcname)
350{
351 if (func(cmdack)) {
352 *retval = -EIO;
353 DPRINTF("%s -> IO error (phase %d)\n", funcname, cmdack->phase);
354 return 1;
355 }
356 if (cmdack->comp_status) {
357 *retval = -EIO;
358 DPRINTF("%s -> Complete parameter error (phase %d), %04X\n", funcname, cmdack->phase, cmdack->comp_status);
359 return 1;
360 }
361 *retval = (cmdack->return_result_word[0] << 16) + cmdack->return_result_word[1];
362 return 0;
363}
364
365int dvrf_df_init(iomanX_iop_device_t *f)
366{
367 int this_sema_id;
368 iop_sema_t sema_struct;
369
370 (void)f;
371
372 if (sema_id >= 0) {
373 return 0;
374 }
375 sema_struct.attr = 0;
376 sema_struct.initial = 1;
377 sema_struct.max = 1;
378 sema_struct.option = 0;
379 this_sema_id = CreateSema(&sema_struct);
380 if (this_sema_id < 0) {
381 return -1;
382 }
383 sema_id = this_sema_id;
384 return 0;
385}
386
387int dvrf_df_exit(iomanX_iop_device_t *f)
388{
389 (void)f;
390
391 if (sema_id < 0) {
392 return 0;
393 }
394 if (DeleteSema(sema_id)) {
395 return -1;
396 }
397 sema_id = -1;
398 return 0;
399}
400
401int dvrf_df_chdir(iomanX_iop_file_t *f, const char *name)
402{
403 int retval;
404 drvdrv_exec_cmd_ack cmdack;
405
406 (void)f;
407
408 WaitSema(sema_id);
409 strcpy((char *)SBUF, name);
410 cmdack.command = 0x1101;
411 cmdack.input_word_count = 0;
412 cmdack.input_buffer = SBUF;
413 cmdack.input_buffer_length = strlen(name) + 1;
414 cmdack.timeout = 10000000;
415 if (check_cmdack_err(&DvrdrvExecCmdAckDmaSendComp, &cmdack, &retval, __func__)) {
416 goto finish;
417 }
418finish:
419 SignalSema(sema_id);
420 return retval;
421}
422
423int dvrf_df_chstat(iomanX_iop_file_t *f, const char *name, iox_stat_t *stat, unsigned int statmask)
424{
425 int retval;
426 drvdrv_exec_cmd_ack cmdack;
427
428 (void)f;
429
430 WaitSema(sema_id);
431 SBUF[0] = statmask;
432 strcpy((char *)&SBUF[1], name);
433 cmdack.command = 0x1102;
434 cmdack.input_buffer = SBUF;
435 cmdack.input_word_count = 2;
436 cmdack.input_buffer_length = strlen(name) + 5;
437 cmdack.output_buffer = RBUF;
438 cmdack.timeout = 10000000;
439 if (check_cmdack_err(&DvrdrvExecCmdAckDma2Comp, &cmdack, &retval, __func__)) {
440 goto finish;
441 }
442 CopySceStat(stat, (u8 *)RBUF);
443finish:
444 SignalSema(sema_id);
445 return retval;
446}
447
448int dvrf_df_close(iomanX_iop_file_t *f)
449{
450 int retval;
451 int dvrp_fd;
452 drvdrv_exec_cmd_ack cmdack;
453
454 retval = 0;
455 WaitSema(sema_id);
456 cmdack.command = 0x1103;
457 dvrp_fd = (int)f->privdata;
458 cmdack.input_word[0] = (dvrp_fd >> 16) & 0xFFFF;
459 cmdack.input_word[1] = dvrp_fd;
460 cmdack.input_word_count = 2;
461 cmdack.timeout = 10000000;
462 if (check_cmdack_err(&DvrdrvExecCmdAckComp, &cmdack, &retval, __func__)) {
463 goto finish;
464 }
465 retval = 0;
466 f->privdata = NULL;
467finish:
468 SignalSema(sema_id);
469 return retval;
470}
471
472int dvrf_df_dclose(iomanX_iop_file_t *f)
473{
474 int retval;
475 int dvrp_fd;
476 drvdrv_exec_cmd_ack cmdack;
477
478 retval = 0;
479 WaitSema(sema_id);
480 cmdack.command = 0x1104;
481 dvrp_fd = (int)f->privdata;
482 cmdack.input_word[0] = (dvrp_fd >> 16) & 0xFFFF;
483 cmdack.input_word[1] = dvrp_fd;
484 cmdack.input_word_count = 2;
485 cmdack.timeout = 10000000;
486 if (check_cmdack_err(&DvrdrvExecCmdAckComp, &cmdack, &retval, __func__)) {
487 goto finish;
488 }
489 retval = 0;
490 f->privdata = NULL;
491finish:
492 SignalSema(sema_id);
493 return retval;
494}
495
496int dvrf_df_devctl(iomanX_iop_file_t *f, const char *name, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen)
497{
498 int retval;
499 u32 argoffset;
500 drvdrv_exec_cmd_ack cmdack;
501
502 (void)f;
503
504 retval = 0;
505 WaitSema(sema_id);
506 if (cmd == 0x5065) {
507 if ((*(u32 *)arg & 0x7F) != 0) {
508 retval = -EINVAL;
509 } else if (*(int *)arg <= 0x20000) {
510 current_chunk_size = *(u32 *)arg;
511 } else {
512 retval = -EDOM;
513 }
514 goto finish;
515 }
516 argoffset = arglen + 16;
517 SBUF[0] = bswap32(argoffset);
518 SBUF[1] = bswap32((u32)cmd);
519 SBUF[2] = bswap32(buflen);
520 SBUF[3] = bswap32(arglen);
521 memcpy(&SBUF[4], arg, arglen);
522 strcpy((char *)SBUF + argoffset, name);
523 cmdack.input_buffer_length = argoffset + strlen(name) + 1;
524 cmdack.command = 0x1105;
525 cmdack.input_word_count = 0;
526 cmdack.input_buffer = SBUF;
527 cmdack.output_buffer = RBUF;
528 cmdack.timeout = 30000000;
529 if (check_cmdack_err(&DvrdrvExecCmdAckDma2Comp, &cmdack, &retval, __func__)) {
530 goto finish;
531 }
532 if (!retval && buf) {
533 memcpy(buf, cmdack.output_buffer, buflen);
534 }
535finish:
536 SignalSema(sema_id);
537 return retval;
538}
539
540int dvrf_df_dopen(iomanX_iop_file_t *f, const char *path)
541{
542 int retval;
543 drvdrv_exec_cmd_ack cmdack;
544
545 WaitSema(sema_id);
546 strcpy((char *)SBUF, path);
547 cmdack.command = 0x1106;
548 cmdack.input_word_count = 0;
549 cmdack.input_buffer = SBUF;
550 cmdack.input_buffer_length = strlen(path) + 1;
551 cmdack.timeout = 10000000;
552 if (check_cmdack_err(&DvrdrvExecCmdAckDmaSendComp, &cmdack, &retval, __func__)) {
553 goto finish;
554 }
555 if (retval < 0) {
556 DPRINTF("%s -> fd error (fd=%d)\n", __func__, retval);
557 goto finish;
558 }
559 f->privdata = (void *)retval;
560finish:
561 SignalSema(sema_id);
562 return retval;
563}
564
565int dvrf_df_dread(iomanX_iop_file_t *f, iox_dirent_t *buf)
566{
567 int dvrp_fd;
568 int retval;
569 drvdrv_exec_cmd_ack cmdack;
570
571 WaitSema(sema_id);
572 cmdack.command = 0x1107;
573 dvrp_fd = (int)f->privdata;
574 cmdack.input_word[0] = (dvrp_fd >> 16) & 0xFFFF;
575 cmdack.input_word[1] = dvrp_fd;
576 cmdack.input_word_count = 2;
577 cmdack.output_buffer = RBUF;
578 cmdack.timeout = 10000000;
579 if (check_cmdack_err(&DvrdrvExecCmdAckDmaRecvComp, &cmdack, &retval, __func__)) {
580 goto finish;
581 }
582 memcpy(buf, RBUF, sizeof(*buf));
583 buf->stat.mode = bswap32(buf->stat.mode);
584 buf->stat.attr = bswap32(buf->stat.attr);
585 buf->stat.size = bswap32(buf->stat.size);
586 buf->stat.hisize = bswap32(buf->stat.hisize);
587 buf->stat.private_0 = bswap32(buf->stat.private_0);
588 buf->stat.private_1 = bswap32(buf->stat.private_1);
589 buf->stat.private_2 = bswap32(buf->stat.private_2);
590 buf->stat.private_3 = bswap32(buf->stat.private_3);
591 buf->stat.private_4 = bswap32(buf->stat.private_4);
592 buf->stat.private_5 = bswap32(buf->stat.private_5);
593 u8 tmp;
594 tmp = buf->stat.ctime[6];
595 buf->stat.ctime[6] = buf->stat.ctime[7];
596 buf->stat.ctime[7] = tmp;
597 tmp = buf->stat.atime[6];
598 buf->stat.atime[6] = buf->stat.atime[7];
599 buf->stat.atime[7] = tmp;
600 tmp = buf->stat.mtime[6];
601 buf->stat.mtime[6] = buf->stat.mtime[7];
602 buf->stat.mtime[7] = tmp;
603finish:
604 SignalSema(sema_id);
605 return retval;
606}
607
608int dvrf_df_format(iomanX_iop_file_t *f, const char *dev, const char *blockdev, void *arg, int arglen)
609{
610 size_t blockdev_len;
611 u32 dev_len;
612 const char *dev_;
613 u32 arg_offset;
614 int retval;
615 drvdrv_exec_cmd_ack cmdack;
616
617 (void)f;
618
619 WaitSema(sema_id);
620 dev_len = strlen(dev) + 13;
621 blockdev_len = strlen(blockdev);
622 dev_ = dev;
623 arg_offset = dev_len + blockdev_len + 1;
624 SBUF[1] = bswap32(arg_offset);
625 SBUF[0] = bswap32(dev_len);
626 SBUF[2] = bswap32(arglen);
627 strcpy((char *)&SBUF[3], dev_);
628 strcpy((char *)SBUF + dev_len, blockdev);
629 memcpy((char *)SBUF + arg_offset, arg, arglen);
630 cmdack.command = 0x1108;
631 cmdack.input_word_count = 0;
632 cmdack.input_buffer = SBUF;
633 cmdack.input_buffer_length = arg_offset + arglen;
634 cmdack.timeout = 3600000000;
635 if (check_cmdack_err(&DvrdrvExecCmdAckDmaSendComp, &cmdack, &retval, __func__)) {
636 goto finish;
637 }
638finish:
639 SignalSema(sema_id);
640 return retval;
641}
642
643int dvrf_df_getstat(iomanX_iop_file_t *f, const char *name, iox_stat_t *stat)
644{
645 int retval;
646 drvdrv_exec_cmd_ack cmdack;
647
648 (void)f;
649
650 WaitSema(sema_id);
651 strcpy((char *)SBUF, name);
652 cmdack.command = 0x1109;
653 cmdack.input_word_count = 0;
654 cmdack.input_buffer = SBUF;
655 cmdack.input_buffer_length = strlen(name) + 1;
656 cmdack.output_buffer = RBUF;
657 cmdack.timeout = 10000000;
658 if (check_cmdack_err(&DvrdrvExecCmdAckDma2Comp, &cmdack, &retval, __func__)) {
659 goto finish;
660 }
661 CopySceStat(stat, (u8 *)RBUF);
662finish:
663 SignalSema(sema_id);
664 return retval;
665}
666
667int dvrf_df_ioctl(iomanX_iop_file_t *f, int cmd, void *param)
668{
669 int dvrp_fd;
670 int retval;
671 drvdrv_exec_cmd_ack cmdack;
672
673 WaitSema(sema_id);
674 dvrp_fd = (int)f->privdata;
675 cmdack.command = 0x110A;
676 cmdack.input_word[0] = (dvrp_fd >> 16) & 0xFFFF;
677 cmdack.input_word[1] = dvrp_fd;
678 cmdack.input_word[2] = (cmd >> 16) & 0xFFFF;
679 cmdack.input_word[3] = cmd;
680 cmdack.input_word[4] = ((u32)param >> 16) & 0xFFFF;
681 cmdack.input_word[5] = (u32)param & 0xFFFF;
682 cmdack.input_word_count = 6;
683 cmdack.timeout = 10000000;
684 if (check_cmdack_err(&DvrdrvExecCmdAckComp, &cmdack, &retval, __func__)) {
685 goto finish;
686 }
687finish:
688 SignalSema(sema_id);
689 return retval;
690}
691
692int dvrf_df_ioctl2(iomanX_iop_file_t *f, int cmd, void *arg, unsigned int arglen, void *buf, unsigned int buflen)
693{
694 int dvrp_fd;
695 int retval;
696 drvdrv_exec_cmd_ack cmdack;
697
698 WaitSema(sema_id);
699 dvrp_fd = (int)f->privdata;
700 SBUF[1] = bswap32(cmd);
701 SBUF[2] = bswap32(buflen);
702 SBUF[0] = bswap32(dvrp_fd);
703 SBUF[3] = bswap32(arglen);
704 memcpy(((u8 *)SBUF) + 0x10, arg, arglen);
705 cmdack.command = 0x110B;
706 cmdack.input_buffer = SBUF;
707 cmdack.input_buffer_length = arglen + 16;
708 cmdack.input_word_count = 0;
709 cmdack.output_buffer = RBUF;
710 cmdack.timeout = 10000000;
711 if (check_cmdack_err(&DvrdrvExecCmdAckDma2Comp, &cmdack, &retval, __func__)) {
712 goto finish;
713 }
714 memcpy(buf, RBUF, buflen);
715finish:
716 SignalSema(sema_id);
717 return retval;
718}
719
720int dvrf_df_lseek(iomanX_iop_file_t *f, int offset, int mode)
721{
722 int dvrp_fd;
723 int retval;
724 drvdrv_exec_cmd_ack cmdack;
725
726 WaitSema(sema_id);
727 dvrp_fd = (int)f->privdata;
728 cmdack.command = 0x110C;
729 cmdack.input_word[0] = (dvrp_fd >> 16) & 0xFFFF;
730 cmdack.input_word[1] = dvrp_fd;
731 cmdack.input_word[2] = (offset >> 16) & 0xFFFF;
732 cmdack.input_word[3] = offset;
733 cmdack.input_word[4] = (mode >> 16) & 0xFFFF;
734 cmdack.input_word[5] = mode;
735 cmdack.input_word_count = 6;
736 cmdack.timeout = 10000000;
737 if (check_cmdack_err(&DvrdrvExecCmdAckComp, &cmdack, &retval, __func__)) {
738 goto finish;
739 }
740finish:
741 SignalSema(sema_id);
742 return retval;
743}
744
745s64 dvrf_df_lseek64(iomanX_iop_file_t *f, s64 offset, int whence)
746{
747 int dvrp_fd;
748 s64 retval;
749 int rretval;
750 drvdrv_exec_cmd_ack cmdack;
751
752 (void)f;
753
754 WaitSema(sema_id);
755 dvrp_fd = (int)f->privdata;
756 cmdack.command = 0x110D;
757 cmdack.input_word[0] = (dvrp_fd >> 16) & 0xFFFF;
758 cmdack.input_word[1] = dvrp_fd;
759 cmdack.input_word[2] = (offset >> 48) & 0xFFFF;
760 cmdack.input_word[3] = (offset >> 32) & 0xFFFF;
761 cmdack.input_word[4] = (offset >> 16) & 0xFFFF;
762 cmdack.input_word[5] = offset;
763 cmdack.input_word[6] = (whence >> 16) & 0xFFFF;
764 cmdack.input_word[7] = whence;
765 cmdack.input_word_count = 8;
766 cmdack.timeout = 10000000;
767 rretval = 0;
768 if (check_cmdack_err(&DvrdrvExecCmdAckComp, &cmdack, &rretval, __func__)) {
769 retval = rretval;
770 goto finish;
771 }
772 retval = ((s64)cmdack.return_result_word[0] << 48) | ((s64)cmdack.return_result_word[1] << 32) | ((s64)cmdack.return_result_word[2] << 16) | (s64)cmdack.return_result_word[3];
773finish:
774 SignalSema(sema_id);
775 return retval;
776}
777
778int dvrf_df_mkdir(iomanX_iop_file_t *f, const char *path, int mode)
779{
780 int retval;
781 drvdrv_exec_cmd_ack cmdack;
782
783 (void)f;
784
785 WaitSema(sema_id);
786 SBUF[0] = bswap32(mode);
787 strcpy((char *)&SBUF[1], path);
788 cmdack.command = 0x110E;
789 cmdack.input_word_count = 0;
790 cmdack.input_buffer = SBUF;
791 cmdack.input_buffer_length = strlen(path) + 5;
792 cmdack.timeout = 10000000;
793 if (check_cmdack_err(&DvrdrvExecCmdAckDmaSendComp, &cmdack, &retval, __func__)) {
794 goto finish;
795 }
796finish:
797 SignalSema(sema_id);
798 return retval;
799}
800
801int dvrf_df_mount(iomanX_iop_file_t *f, const char *fsname, const char *devname, int flag, void *arg, int arglen)
802{
803 size_t devname_len;
804 u32 fsname_len;
805 const char *fsname_;
806 unsigned int arg_offs;
807 int retval;
808 drvdrv_exec_cmd_ack cmdack;
809
810 (void)f;
811
812 WaitSema(sema_id);
813 SBUF[0] = bswap32(flag);
814 fsname_len = strlen(fsname) + 17;
815 devname_len = strlen(devname);
816 fsname_ = fsname;
817 arg_offs = fsname_len + devname_len + 1;
818 SBUF[2] = bswap32(arg_offs);
819 SBUF[1] = bswap32(fsname_len);
820 SBUF[3] = bswap32(arglen);
821 strcpy((char *)&SBUF[4], fsname_);
822 strcpy((char *)SBUF + fsname_len, devname);
823 memcpy(((u8 *)SBUF) + arg_offs, arg, arglen);
824
825 cmdack.command = 0x110F;
826 cmdack.input_buffer = SBUF;
827 cmdack.input_word_count = 0;
828 cmdack.input_buffer_length = arg_offs + arglen;
829 cmdack.timeout = 10000000;
830 if (check_cmdack_err(&DvrdrvExecCmdAckDmaSendComp, &cmdack, &retval, __func__)) {
831 goto finish;
832 }
833finish:
834 SignalSema(sema_id);
835 return retval;
836}
837
838int dvrf_df_open(iomanX_iop_file_t *f, const char *name, int flags, int mode)
839{
840 u16 mode_;
841 int retval;
842 drvdrv_exec_cmd_ack cmdack;
843
844 mode_ = mode;
845 WaitSema(sema_id);
846 SBUF[0] = bswap32(flags);
847 mode_ = (mode_ << 8) + (mode_ >> 8);
848 memcpy(&SBUF[1], &mode_, sizeof(mode_));
849 strcpy((char *)&SBUF[1] + 2, name);
850 cmdack.command = 0x1110;
851 cmdack.input_word_count = 0;
852 cmdack.input_buffer = SBUF;
853 cmdack.input_buffer_length = strlen(name) + 7;
854 cmdack.timeout = 10000000;
855 if (check_cmdack_err(&DvrdrvExecCmdAckDmaSendComp, &cmdack, &retval, __func__)) {
856 goto finish;
857 }
858 if (retval < 0) {
859 DPRINTF("%s -> fd error (fd=%d)\n", __func__, retval);
860 goto finish;
861 }
862 f->privdata = (void *)retval;
863finish:
864 SignalSema(sema_id);
865 return retval;
866}
867
868int dvrf_df_read(iomanX_iop_file_t *f, void *ptr, int size)
869{
870 size_t total_read;
871 char *out_buf;
872 int retval;
873 int dvrp_fd;
874 int remain_size;
875 int chunk_size;
876 int unaligned_size;
877 drvdrv_exec_cmd_ack cmdack;
878
879 total_read = 0;
880 unaligned_size = 0;
881 if (((u32)ptr & 3) != 0) {
882 unaligned_size = 4 - ((u32)ptr & 3);
883 }
884 WaitSema(sema_id);
885 out_buf = (char *)ptr;
886 dvrp_fd = (int)f->privdata;
887 remain_size = size;
888 cmdack.command = 0x1111;
889 cmdack.input_word[0] = (dvrp_fd >> 16) & 0xFFFF;
890 cmdack.input_word[1] = dvrp_fd;
891 cmdack.input_word_count = 4;
892 cmdack.timeout = 10000000;
893 while (1) {
894 int read_size;
895 if (remain_size <= 0) {
896 break;
897 }
898 chunk_size = current_chunk_size;
899 if (remain_size < current_chunk_size) {
900 chunk_size = remain_size;
901 }
902 if (unaligned_size != 0) {
903 chunk_size = unaligned_size;
904 }
905 cmdack.input_word[2] = (chunk_size >> 16) & 0xFFFF;
906 cmdack.input_word[3] = chunk_size;
907 if ((chunk_size & 0x7F) != 0 || unaligned_size != 0) {
908 cmdack.output_buffer = (char *)RBUF;
909 } else {
910 cmdack.output_buffer = out_buf;
911 }
912 if (check_cmdack_err(&DvrdrvExecCmdAckDmaRecvComp, &cmdack, &read_size, __func__)) {
913 retval = read_size;
914 goto finish;
915 }
916 if ((chunk_size & 0x7F) != 0 || unaligned_size != 0) {
917 memcpy(out_buf, RBUF, chunk_size);
918 unaligned_size = 0;
919 }
920 if (read_size <= 0) {
921 break;
922 }
923 remain_size -= read_size;
924 out_buf += read_size;
925 total_read += read_size;
926 }
927 retval = total_read;
928finish:
929 SignalSema(sema_id);
930 return retval;
931}
932
933int dvrf_df_readlink(iomanX_iop_file_t *f, const char *path, char *buf, unsigned int buflen)
934{
935 int retval;
936 drvdrv_exec_cmd_ack cmdack;
937
938 (void)f;
939
940 WaitSema(sema_id);
941 SBUF[0] = bswap32(buflen);
942 strcpy((char *)&SBUF[1], path);
943 cmdack.input_buffer_length = strlen(path) + 5;
944 cmdack.command = 0x1112;
945 cmdack.input_word_count = 0;
946 cmdack.input_buffer = SBUF;
947 cmdack.output_buffer = RBUF;
948 cmdack.timeout = 10000000;
949 if (check_cmdack_err(&DvrdrvExecCmdAckDma2Comp, &cmdack, &retval, __func__)) {
950 goto finish;
951 }
952 memcpy(buf, RBUF, buflen);
953finish:
954 SignalSema(sema_id);
955 return retval;
956}
957
958int dvrf_df_remove(iomanX_iop_file_t *f, const char *name)
959{
960 int retval;
961 drvdrv_exec_cmd_ack cmdack;
962
963 (void)f;
964
965 WaitSema(sema_id);
966 strcpy((char *)SBUF, name);
967 cmdack.command = 0x1113;
968 cmdack.input_word_count = 0;
969 cmdack.input_buffer = SBUF;
970 cmdack.input_buffer_length = strlen(name) + 1;
971 cmdack.timeout = 10000000;
972 if (check_cmdack_err(&DvrdrvExecCmdAckDmaSendComp, &cmdack, &retval, __func__)) {
973 goto finish;
974 }
975finish:
976 SignalSema(sema_id);
977 return retval;
978}
979
980int dvrf_df_rename(iomanX_iop_file_t *f, const char *old, const char *new_1)
981{
982 size_t old_strlen;
983 const char *old_;
984 size_t new_offs;
985 int retval;
986 drvdrv_exec_cmd_ack cmdack;
987
988 (void)f;
989
990 WaitSema(sema_id);
991 old_strlen = strlen(old);
992 old_ = old;
993 new_offs = old_strlen + 5;
994 SBUF[0] = bswap32(new_offs);
995 strcpy((char *)&SBUF[1], old_);
996 strcpy((char *)SBUF + new_offs, new_1);
997 cmdack.command = 0x1114;
998 cmdack.input_word_count = 0;
999 cmdack.input_buffer = SBUF;
1000 cmdack.input_buffer_length = new_offs + strlen(new_1) + 1;
1001 cmdack.timeout = 10000000;
1002 if (check_cmdack_err(&DvrdrvExecCmdAckDmaSendComp, &cmdack, &retval, __func__)) {
1003 goto finish;
1004 }
1005finish:
1006 SignalSema(sema_id);
1007 return retval;
1008}
1009
1010int dvrf_df_rmdir(iomanX_iop_file_t *f, const char *path)
1011{
1012 int retval;
1013 drvdrv_exec_cmd_ack cmdack;
1014
1015 (void)f;
1016
1017 WaitSema(sema_id);
1018 strcpy((char *)SBUF, path);
1019 cmdack.command = 0x1115;
1020 cmdack.input_word_count = 0;
1021 cmdack.input_buffer = SBUF;
1022 cmdack.input_buffer_length = strlen(path) + 1;
1023 cmdack.timeout = 10000000;
1024 if (check_cmdack_err(&DvrdrvExecCmdAckDmaSendComp, &cmdack, &retval, __func__)) {
1025 goto finish;
1026 }
1027finish:
1028 SignalSema(sema_id);
1029 return retval;
1030}
1031
1032int dvrf_df_symlink(iomanX_iop_file_t *f, const char *old, const char *new_1)
1033{
1034 size_t old_len;
1035 const char *old_;
1036 size_t new_offs;
1037 int retval;
1038 drvdrv_exec_cmd_ack cmdack;
1039
1040 (void)f;
1041
1042 WaitSema(sema_id);
1043 old_len = strlen(old);
1044 old_ = old;
1045 new_offs = old_len + 5;
1046 SBUF[0] = bswap32(new_offs);
1047 strcpy((char *)&SBUF[1], old_);
1048 strcpy((char *)SBUF + new_offs, new_1);
1049 cmdack.command = 0x1116;
1050 cmdack.input_word_count = 0;
1051 cmdack.input_buffer = SBUF;
1052 cmdack.input_buffer_length = new_offs + strlen(new_1) + 1;
1053 cmdack.timeout = 10000000;
1054 if (check_cmdack_err(&DvrdrvExecCmdAckDmaSendComp, &cmdack, &retval, __func__)) {
1055 goto finish;
1056 }
1057finish:
1058 SignalSema(sema_id);
1059 return retval;
1060}
1061
1062int dvrf_df_sync(iomanX_iop_file_t *f, const char *dev, int flag)
1063{
1064 int retval;
1065 drvdrv_exec_cmd_ack cmdack;
1066
1067 (void)f;
1068
1069 WaitSema(sema_id);
1070 SBUF[0] = bswap32(flag);
1071 strcpy((char *)&SBUF[1], dev);
1072 cmdack.command = 0x1117;
1073 cmdack.input_word_count = 0;
1074 cmdack.input_buffer = SBUF;
1075 cmdack.input_buffer_length = strlen(dev) + 5;
1076 cmdack.timeout = 10000000;
1077 if (check_cmdack_err(&DvrdrvExecCmdAckDmaSendComp, &cmdack, &retval, __func__)) {
1078 goto finish;
1079 }
1080finish:
1081 SignalSema(sema_id);
1082 return retval;
1083}
1084
1085int dvrf_df_umount(iomanX_iop_file_t *f, const char *fsname)
1086{
1087 int retval;
1088 drvdrv_exec_cmd_ack cmdack;
1089
1090 (void)f;
1091
1092 WaitSema(sema_id);
1093 strcpy((char *)SBUF, fsname);
1094 cmdack.command = 0x1118;
1095 cmdack.input_word_count = 0;
1096 cmdack.input_buffer = SBUF;
1097 cmdack.input_buffer_length = strlen(fsname) + 1;
1098 cmdack.timeout = 10000000;
1099 if (check_cmdack_err(&DvrdrvExecCmdAckDmaSendComp, &cmdack, &retval, __func__)) {
1100 goto finish;
1101 }
1102finish:
1103 SignalSema(sema_id);
1104 return retval;
1105}
1106
1107int dvrf_df_write(iomanX_iop_file_t *f, void *ptr, int size)
1108{
1109 int total_write;
1110 char *in_buffer;
1111 int retval;
1112 int dvrp_fd;
1113 int remain_size;
1114 int unaligned_size;
1115 drvdrv_exec_cmd_ack cmdack;
1116
1117 total_write = 0;
1118 in_buffer = (char *)ptr;
1119 unaligned_size = 0;
1120 if (((u32)ptr & 3) != 0) {
1121 unaligned_size = 4 - ((u32)ptr & 3);
1122 memcpy(RBUF, ptr, unaligned_size);
1123 }
1124 WaitSema(sema_id);
1125 dvrp_fd = (int)f->privdata;
1126 remain_size = size;
1127 cmdack.command = 0x1119;
1128 cmdack.input_word[0] = (dvrp_fd >> 16) & 0xFFFF;
1129 cmdack.input_word[1] = dvrp_fd;
1130 cmdack.input_word_count = 4;
1131 cmdack.timeout = 10000000;
1132 while (remain_size > 0) {
1133 u32 chunk_size;
1134 chunk_size = current_chunk_size;
1135 if (remain_size < current_chunk_size) {
1136 chunk_size = remain_size;
1137 }
1138 if (unaligned_size != 0) {
1139 chunk_size = unaligned_size;
1140 }
1141 cmdack.input_word[2] = (chunk_size >> 16) & 0xFFFF;
1142 cmdack.input_word[3] = chunk_size;
1143 if (unaligned_size != 0) {
1144 cmdack.input_buffer = (char *)RBUF;
1145 unaligned_size = 0;
1146 } else {
1147 cmdack.input_buffer = in_buffer;
1148 }
1149 cmdack.input_buffer_length = chunk_size;
1150 if (check_cmdack_err(&DvrdrvExecCmdAckDmaSendComp, &cmdack, &retval, __func__)) {
1151 goto finish;
1152 }
1153 if (retval <= 0) {
1154 goto finish;
1155 }
1156 remain_size -= retval;
1157 in_buffer += retval;
1158 total_write += retval;
1159 }
1160 retval = total_write;
1161finish:
1162 SignalSema(sema_id);
1163 return retval;
1164}
1165
1166void CopySceStat(iox_stat_t *stat, u8 *dvrp_stat)
1167{
1168 stat->mode = bswap32(((u32 *)dvrp_stat)[0]);
1169 stat->attr = bswap32(((u32 *)dvrp_stat)[1]);
1170 stat->size = bswap32(((u32 *)dvrp_stat)[2]);
1171 memcpy(stat->ctime, &((u32 *)dvrp_stat)[3], 6);
1172 stat->ctime[6] = ((u8 *)dvrp_stat)[19];
1173 stat->ctime[7] = ((u8 *)dvrp_stat)[18];
1174 memcpy(stat->atime, &((u32 *)dvrp_stat)[5], 6);
1175 stat->atime[6] = ((u8 *)dvrp_stat)[27];
1176 stat->atime[7] = ((u8 *)dvrp_stat)[26];
1177 memcpy(stat->mtime, &((u32 *)dvrp_stat)[7], 6);
1178 stat->mtime[6] = ((u8 *)dvrp_stat)[35];
1179 stat->mtime[7] = ((u8 *)dvrp_stat)[34];
1180 stat->hisize = bswap32(((u32 *)dvrp_stat)[9]);
1181 stat->private_0 = bswap32(((u32 *)dvrp_stat)[10]);
1182 stat->private_1 = bswap32(((u32 *)dvrp_stat)[11]);
1183 stat->private_2 = bswap32(((u32 *)dvrp_stat)[12]);
1184 stat->private_3 = bswap32(((u32 *)dvrp_stat)[13]);
1185 stat->private_4 = bswap32(((u32 *)dvrp_stat)[14]);
1186 stat->private_5 = bswap32(((u32 *)dvrp_stat)[15]);
1187}
#define EINVAL
Definition errno.h:63
#define EDOM
Definition errno.h:85
#define EIO
Definition errno.h:29
struct _iomanX_iop_device * device
Definition iomanX.h:76
void * privdata
Definition iomanX.h:78
unsigned int private_0
Definition iox_stat.h:102
unsigned int private_5
Definition iox_stat.h:108
u16 newflags
Definition loadcore.h:36