11#define MMCE_FS_MAX_FD 16
12#define MMCE_FS_WAIT_TIMEOUT 128000
14#define NOT_SUPPORTED_OP (void*)¬_supported_operation
15static int not_supported_operation() {
19static int mmce_fs_fds[MMCE_FS_MAX_FD];
20static int last_unit = -1;
22static int *mmce_fs_find_free_handle(
void) {
23 for (
int i = 0; i < MMCE_FS_MAX_FD; i++)
25 if (mmce_fs_fds[i] < 0)
26 return &mmce_fs_fds[i];
32static int mmce_fs_update_unit(
int unit)
36 if (unit != last_unit) {
44 DPRINTF(
"Unit changed, unit: %i port: %i\n", unit, port);
45 mmce_sio2_set_port(port);
51int mmce_fs_init(iomanX_iop_device_t *f)
53 DPRINTF(
"%s: init\n", __func__);
54 memset(mmce_fs_fds, -1,
sizeof(mmce_fs_fds));
58int mmce_fs_deinit(iomanX_iop_device_t *f)
63int mmce_fs_open(iomanX_iop_file_t *file,
const char *name,
int flags,
int mode)
70 DPRINTF(
"%s unit: %i name: %s flags: 0x%x\n", __func__, file->unit, name, flags);
73 mmce_fs_update_unit(file->unit);
76 file->privdata = (
int*)mmce_fs_find_free_handle();
78 if (file->privdata == NULL) {
79 DPRINTF(
"%s ERROR: No free file handles available\n", __func__);
84 u8 filename_len = strlen(name) + 1;
86 packed_flags = (flags & 3) - 1;
87 packed_flags |= (flags & 0x100) >> 5;
88 packed_flags |= (flags & 0xE00) >> 4;
91 wrbuf[0x1] = MMCE_CMD_FS_OPEN;
92 wrbuf[0x2] = MMCE_RESERVED;
93 wrbuf[0x3] = packed_flags;
99 res = mmce_sio2_tx_rx_pio(0x5, 0x2, wrbuf, rdbuf, &timeout_1s);
101 DPRINTF(
"%s ERROR: P1 - Timedout waiting for /ACK\n", __func__);
106 if (rdbuf[0x1] != MMCE_REPLY_CONST) {
107 DPRINTF(
"%s ERROR: Invalid response from card. Got 0x%x, Expected 0x%x\n", __func__, rdbuf[0x1], MMCE_REPLY_CONST);
113 res = mmce_sio2_tx_rx_pio(filename_len, 0x0, name, NULL, &timeout_1s);
115 DPRINTF(
"%s ERROR: P2 - Timedout waiting for /ACK\n", __func__);
121 res = mmce_sio2_tx_rx_pio(0x0, 0x3, wrbuf, rdbuf, &timeout_1s);
124 DPRINTF(
"%s ERROR: P3 - Timedout waiting for /ACK\n", __func__);
128 if (rdbuf[0x1] != 0xff) {
129 *(
int*)file->privdata = rdbuf[0x1];
130 DPRINTF(
"%s Opened fd: %i\n", __func__, rdbuf[0x1]);
132 DPRINTF(
"%s ERROR: Got bad fd: %i\n", __func__, rdbuf[0x1]);
133 file->privdata = NULL;
140int mmce_fs_close(iomanX_iop_file_t *file)
147 DPRINTF(
"%s fd: %i\n", __func__, (u8)*(
int*)file->privdata);
149 mmce_fs_update_unit(file->unit);
152 if (*(
int*)file->privdata >= 250)
155 wrbuf[0x0] = MMCE_ID;
156 wrbuf[0x1] = MMCE_CMD_FS_CLOSE;
157 wrbuf[0x2] = MMCE_RESERVED;
158 wrbuf[0x3] = (u8)*(
int*)file->privdata;
162 res = mmce_sio2_tx_rx_pio(0x4, 0x6, wrbuf, rdbuf, &timeout_1s);
166 DPRINTF(
"%s ERROR: P1 - Timedout waiting for /ACK\n", __func__);
170 if (rdbuf[0x1] != MMCE_REPLY_CONST) {
171 DPRINTF(
"%s ERROR: Invalid response from card. Got 0x%x, Expected 0x%x\n", __func__, rdbuf[0x1], MMCE_REPLY_CONST);
175 if (rdbuf[0x4] == 0x0) {
176 *(
int*)file->privdata = -1;
179 DPRINTF(
"%s ERROR: got return value %i\n", __func__, res);
185int mmce_fs_read(iomanX_iop_file_t *file,
void *ptr,
int size)
193 DPRINTF(
"%s fd: %i, size: %i\n", __func__, (u8)*(
int*)file->privdata, size);
195 mmce_fs_update_unit(file->unit);
197 wrbuf[0x0] = MMCE_ID;
198 wrbuf[0x1] = MMCE_CMD_FS_READ;
199 wrbuf[0x2] = MMCE_RESERVED;
201 wrbuf[0x4] = (u8)*(
int*)file->privdata;
202 wrbuf[0x5] = (size & 0xFF000000) >> 24;
203 wrbuf[0x6] = (size & 0x00FF0000) >> 16;
204 wrbuf[0x7] = (size & 0x0000FF00) >> 8;
205 wrbuf[0x8] = (size & 0x000000FF);
211 res = mmce_sio2_tx_rx_pio(0xA, 0xA, wrbuf, rdbuf, &timeout_2s);
213 DPRINTF(
"%s ERROR: P1 - Timedout waiting for /ACK\n", __func__);
218 if (rdbuf[0x1] != MMCE_REPLY_CONST) {
219 DPRINTF(
"%s ERROR: Invalid response from card. Got 0x%x, Expected 0x%x\n", __func__, rdbuf[0x1], MMCE_REPLY_CONST);
224 if (rdbuf[0x9] != 0x0) {
225 DPRINTF(
"%s ERROR: P1 - Got bad return value from card, res %i\n", __func__, rdbuf[0x9]);
231 res = mmce_sio2_rx_mixed(ptr, size);
233 DPRINTF(
"%s ERROR: P2 - Timedout waiting for /ACK\n", __func__);
239 res = mmce_sio2_tx_rx_pio(0x0, 0x6, wrbuf, rdbuf, &timeout_1s);
241 DPRINTF(
"%s ERROR: P3 - Timedout waiting for /ACK\n", __func__);
248 bytes_read = rdbuf[0x1] << 24;
249 bytes_read |= rdbuf[0x2] << 16;
250 bytes_read |= rdbuf[0x3] << 8;
251 bytes_read |= rdbuf[0x4];
253 if (bytes_read != size) {
254 DPRINTF(
"%s WARN: bytes read: %i, expected: %i\n", __func__, bytes_read, size);
256 if (bytes_read > size)
264int mmce_fs_write(iomanX_iop_file_t *file,
void *ptr,
int size)
272 DPRINTF(
"%s fd: %i, size: %i\n", __func__, (u8)*(
int*)file->privdata, size);
274 mmce_fs_update_unit(file->unit);
276 wrbuf[0x0] = MMCE_ID;
277 wrbuf[0x1] = MMCE_CMD_FS_WRITE;
278 wrbuf[0x2] = MMCE_RESERVED;
280 wrbuf[0x4] = (u8)*(
int*)file->privdata;
281 wrbuf[0x5] = (size & 0xFF000000) >> 24;
282 wrbuf[0x6] = (size & 0x00FF0000) >> 16;
283 wrbuf[0x7] = (size & 0x0000FF00) >> 8;
284 wrbuf[0x8] = (size & 0x000000FF);
290 res = mmce_sio2_tx_rx_pio(0xA, 0xA, wrbuf, rdbuf, &timeout_1s);
292 DPRINTF(
"%s ERROR: P1 - Timedout waiting for /ACK\n", __func__);
297 if (rdbuf[0x1] != MMCE_REPLY_CONST) {
298 DPRINTF(
"%s ERROR: Invalid response from card. Got 0x%x, Expected 0x%x\n", __func__, rdbuf[0x1], MMCE_REPLY_CONST);
303 if (rdbuf[0x9] != 0x0) {
304 DPRINTF(
"%s ERROR: P1 - Got bad return value from card 0x%x\n", __func__, rdbuf[0x9]);
310 res = mmce_sio2_tx_mixed(ptr, size);
312 DPRINTF(
"%s ERROR: P2 - Timedout waiting for /ACK\n", __func__);
318 res = mmce_sio2_tx_rx_pio(0x0, 0x6, wrbuf, rdbuf, &timeout_1s);
320 DPRINTF(
"%s ERROR: P3 - Timedout waiting for /ACK\n", __func__);
327 bytes_written = rdbuf[0x1] << 24;
328 bytes_written |= rdbuf[0x2] << 16;
329 bytes_written |= rdbuf[0x3] << 8;
330 bytes_written |= rdbuf[0x4];
332 if (bytes_written != size) {
333 DPRINTF(
"%s bytes written: %i, expected: %i\n", __func__, bytes_written, size);
336 return bytes_written;
339int mmce_fs_lseek(iomanX_iop_file_t *file,
int offset,
int whence)
347 DPRINTF(
"%s fd: %i, offset: %i, whence: %i\n", __func__, (u8)*(
int*)file->privdata, offset, whence);
349 mmce_fs_update_unit(file->unit);
351 wrbuf[0x0] = MMCE_ID;
352 wrbuf[0x1] = MMCE_CMD_FS_LSEEK;
353 wrbuf[0x2] = MMCE_RESERVED;
354 wrbuf[0x3] = (u8)(*(
int*)file->privdata);
355 wrbuf[0x4] = (offset & 0xFF000000) >> 24;
356 wrbuf[0x5] = (offset & 0x00FF0000) >> 16;
357 wrbuf[0x6] = (offset & 0x0000FF00) >> 8;
358 wrbuf[0x7] = (offset & 0x000000FF);
359 wrbuf[0x8] = (u8)(whence);
363 res = mmce_sio2_tx_rx_pio(0x9, 0xe, wrbuf, rdbuf, &timeout_1s);
367 DPRINTF(
"%s ERROR: P1 - Timedout waiting for /ACK\n", __func__);
371 if (rdbuf[0x1] != MMCE_REPLY_CONST) {
372 DPRINTF(
"%s ERROR: Invalid response from card. Got 0x%x, Expected 0x%x\n", __func__, rdbuf[0x1], MMCE_REPLY_CONST);
376 position = rdbuf[0x9] << 24;
377 position |= rdbuf[0xa] << 16;
378 position |= rdbuf[0xb] << 8;
379 position |= rdbuf[0xc];
381 DPRINTF(
"%s position %i\n", __func__, position);
386int mmce_fs_ioctl(iomanX_iop_file_t *file,
int cmd,
void *data)
393int mmce_fs_remove(iomanX_iop_file_t *file,
const char *name)
400 DPRINTF(
"%s name: %s\n", __func__, name);
402 mmce_fs_update_unit(file->unit);
404 u8 filename_len = strlen(name) + 1;
406 wrbuf[0x0] = MMCE_ID;
407 wrbuf[0x1] = MMCE_CMD_FS_REMOVE;
408 wrbuf[0x2] = MMCE_RESERVED;
414 res = mmce_sio2_tx_rx_pio(0x4, 0x2, wrbuf, rdbuf, &timeout_1s);
416 DPRINTF(
"%s ERROR: P1 - Timedout waiting for /ACK\n", __func__);
421 if (rdbuf[0x1] != MMCE_REPLY_CONST) {
422 DPRINTF(
"%s ERROR: Invalid response from card. Got 0x%x, Expected 0x%x\n", __func__, rdbuf[0x1], MMCE_REPLY_CONST);
428 res = mmce_sio2_tx_rx_pio(filename_len, 0x0, name, NULL, &timeout_1s);
430 DPRINTF(
"%s ERROR: P2 - Timedout waiting for /ACK\n", __func__);
436 res = mmce_sio2_tx_rx_pio(0x0, 0x3, NULL, rdbuf, &timeout_1s);
440 DPRINTF(
"%s ERROR: P3 - Timedout waiting for /ACK\n", __func__);
444 if (rdbuf[0x1] != 0x0) {
445 DPRINTF(
"%s ERROR: Card failed to remove %s, return value %i\n", __func__, name, rdbuf[0x1]);
452int mmce_fs_mkdir(iomanX_iop_file_t *file,
const char *name,
int flags)
459 DPRINTF(
"%s name: %s\n", __func__, name);
461 mmce_fs_update_unit(file->unit);
463 u8 dir_len = strlen(name) + 1;
465 wrbuf[0x0] = MMCE_ID;
466 wrbuf[0x1] = MMCE_CMD_FS_MKDIR;
467 wrbuf[0x2] = MMCE_RESERVED;
473 res = mmce_sio2_tx_rx_pio(0x4, 0x2, wrbuf, rdbuf, &timeout_1s);
475 DPRINTF(
"%s ERROR: P1 - Timedout waiting for /ACK\n", __func__);
480 if (rdbuf[0x1] != MMCE_REPLY_CONST) {
481 DPRINTF(
"%s ERROR: Invalid response from card. Got 0x%x, Expected 0x%x\n", __func__, rdbuf[0x1], MMCE_REPLY_CONST);
487 res = mmce_sio2_tx_rx_pio(dir_len, 0x0, name, NULL, &timeout_1s);
489 DPRINTF(
"%s ERROR: P2 - Timedout waiting for /ACK\n", __func__);
495 res = mmce_sio2_tx_rx_pio(0x0, 0x3, NULL, rdbuf, &timeout_1s);
499 DPRINTF(
"%s ERROR: P3 - Timedout waiting for /ACK\n", __func__);
503 if (rdbuf[0x1] != 0x0) {
504 DPRINTF(
"%s ERROR: Card failed to mkdir %s, return value %i\n", __func__, name, rdbuf[0x1]);
511int mmce_fs_rmdir(iomanX_iop_file_t *file,
const char *name)
518 DPRINTF(
"%s name: %s\n", __func__, name);
520 mmce_fs_update_unit(file->unit);
522 u8 dir_len = strlen(name) + 1;
524 wrbuf[0x0] = MMCE_ID;
525 wrbuf[0x1] = MMCE_CMD_FS_RMDIR;
526 wrbuf[0x2] = MMCE_RESERVED;
532 res = mmce_sio2_tx_rx_pio(0x4, 0x2, wrbuf, rdbuf, &timeout_1s);
534 DPRINTF(
"%s ERROR: P1 - Timedout waiting for /ACK\n", __func__);
539 if (rdbuf[0x1] != MMCE_REPLY_CONST) {
540 DPRINTF(
"%s ERROR: Invalid response from card. Got 0x%x, Expected 0x%x\n", __func__, rdbuf[0x1], MMCE_REPLY_CONST);
546 res = mmce_sio2_tx_rx_pio(dir_len, 0x0, name, NULL, &timeout_1s);
548 DPRINTF(
"%s ERROR: P2 - Timedout waiting for /ACK\n", __func__);
554 res = mmce_sio2_tx_rx_pio(0x0, 0x3, NULL, rdbuf, &timeout_1s);
558 DPRINTF(
"%s ERROR: P3 - Timedout waiting for /ACK\n", __func__);
562 if (rdbuf[0x1] != 0x0) {
563 DPRINTF(
"%s ERROR: Card failed to rmdir %s, return value %i\n", __func__, name, rdbuf[0x1]);
570int mmce_fs_dopen(iomanX_iop_file_t *file,
const char *name)
577 DPRINTF(
"%s name: %s\n", __func__, name);
579 mmce_fs_update_unit(file->unit);
581 file->privdata = (
int*)mmce_fs_find_free_handle();
583 if (file->privdata == NULL) {
584 DPRINTF(
"%s ERROR: No free file handles available\n", __func__);
588 u8 dir_len = strlen(name) + 1;
590 wrbuf[0x0] = MMCE_ID;
591 wrbuf[0x1] = MMCE_CMD_FS_DOPEN;
592 wrbuf[0x2] = MMCE_RESERVED;
598 res = mmce_sio2_tx_rx_pio(0x4, 0x2, wrbuf, rdbuf, &timeout_1s);
600 DPRINTF(
"%s ERROR: P1 - Timedout waiting for /ACK\n", __func__);
605 if (rdbuf[0x1] != MMCE_REPLY_CONST) {
606 DPRINTF(
"%s ERROR: Invalid response from card. Got 0x%x, Expected 0x%x\n", __func__, rdbuf[0x1], MMCE_REPLY_CONST);
612 res = mmce_sio2_tx_rx_pio(dir_len, 0x0, name, NULL, &timeout_1s);
614 DPRINTF(
"%s ERROR: P2 - Timedout waiting for /ACK\n", __func__);
620 res = mmce_sio2_tx_rx_pio(0x0, 0x3, NULL, rdbuf, &timeout_1s);
624 DPRINTF(
"%s ERROR: P3 - Timedout waiting for /ACK\n", __func__);
628 if (rdbuf[0x1] != 0xff) {
629 *(
int*)file->privdata = rdbuf[0x1];
631 DPRINTF(
"%s ERROR: Got invalid fd: %i\n", __func__, rdbuf[0x1]);
632 file->privdata = NULL;
639int mmce_fs_dclose(iomanX_iop_file_t *file)
646 mmce_fs_update_unit(file->unit);
648 wrbuf[0x0] = MMCE_ID;
649 wrbuf[0x1] = MMCE_CMD_FS_DCLOSE;
650 wrbuf[0x2] = MMCE_RESERVED;
651 wrbuf[0x3] = (u8)*(
int*)file->privdata;
653 DPRINTF(
"%s fd: %i\n", __func__, (u8)*(
int*)file->privdata);
657 res = mmce_sio2_tx_rx_pio(0x4, 0x6, wrbuf, rdbuf, &timeout_1s);
661 DPRINTF(
"%s ERROR: P1 - Timedout waiting for /ACK\n", __func__);
665 if (rdbuf[0x1] != MMCE_REPLY_CONST) {
666 DPRINTF(
"%s ERROR: Invalid response from card. Got 0x%x, Expected 0x%x\n", __func__, rdbuf[0x1], MMCE_REPLY_CONST);
670 if (rdbuf[0x4] != 0x0) {
671 DPRINTF(
"%s ERROR: Card failed to close dir %i, return value %i\n", __func__, (u8)*(
int*)file->privdata, rdbuf[0x1]);
675 *(
int*)file->privdata = -1;
676 file->privdata = NULL;
681int mmce_fs_dread(iomanX_iop_file_t *file, iox_dirent_t *dirent)
688 DPRINTF(
"%s fd: %i\n", __func__, (u8)*(
int*)file->privdata);
690 mmce_fs_update_unit(file->unit);
694 wrbuf[0x0] = MMCE_ID;
695 wrbuf[0x1] = MMCE_CMD_FS_DREAD;
696 wrbuf[0x2] = MMCE_RESERVED;
697 wrbuf[0x3] = (u8)*(
int*)file->privdata;
700 DPRINTF(
"%s fd: %i\n", __func__, (u8)*(
int*)file->privdata);
705 res = mmce_sio2_tx_rx_pio(0x5, 0x5, wrbuf, rdbuf, &timeout_1s);
707 DPRINTF(
"%s ERROR: P1 - Timedout waiting for /ACK\n", __func__);
712 if (rdbuf[0x1] != MMCE_REPLY_CONST) {
713 DPRINTF(
"%s ERROR: Invalid response from card. Got 0x%x, Expected 0x%x\n", __func__, rdbuf[0x1], MMCE_REPLY_CONST);
718 if (rdbuf[0x4] != 0) {
719 DPRINTF(
"%s ERROR: Returned %i, Expected 0\n", __func__, rdbuf[0x4]);
725 res = mmce_sio2_tx_rx_pio(0x0, 0x2A, NULL, rdbuf, &timeout_1s);
727 DPRINTF(
"%s ERROR: P3 - Timedout waiting for /ACK\n", __func__);
733 dirent->stat.mode = rdbuf[0x1] << 24;
734 dirent->stat.mode |= rdbuf[0x2] << 16;
735 dirent->stat.mode |= rdbuf[0x3] << 8;
736 dirent->stat.mode |= rdbuf[0x4];
738 dirent->stat.attr = rdbuf[0x5] << 24;
739 dirent->stat.attr |= rdbuf[0x6] << 16;
740 dirent->stat.attr |= rdbuf[0x7] << 8;
741 dirent->stat.attr |= rdbuf[0x8];
743 dirent->stat.size = rdbuf[0x9] << 24;
744 dirent->stat.size |= rdbuf[0xA] << 16;
745 dirent->stat.size |= rdbuf[0xB] << 8;
746 dirent->stat.size |= rdbuf[0xC];
748 dirent->stat.ctime[0] = rdbuf[0xD];
749 dirent->stat.ctime[1] = rdbuf[0xE];
750 dirent->stat.ctime[2] = rdbuf[0xF];
751 dirent->stat.ctime[3] = rdbuf[0x10];
752 dirent->stat.ctime[4] = rdbuf[0x11];
753 dirent->stat.ctime[5] = rdbuf[0x12];
754 dirent->stat.ctime[6] = rdbuf[0x13];
755 dirent->stat.ctime[7] = rdbuf[0x14];
757 dirent->stat.atime[0] = rdbuf[0x15];
758 dirent->stat.atime[1] = rdbuf[0x16];
759 dirent->stat.atime[2] = rdbuf[0x17];
760 dirent->stat.atime[3] = rdbuf[0x18];
761 dirent->stat.atime[4] = rdbuf[0x19];
762 dirent->stat.atime[5] = rdbuf[0x1A];
763 dirent->stat.atime[6] = rdbuf[0x1B];
764 dirent->stat.atime[7] = rdbuf[0x1C];
766 dirent->stat.mtime[0] = rdbuf[0x1D];
767 dirent->stat.mtime[1] = rdbuf[0x1E];
768 dirent->stat.mtime[2] = rdbuf[0x1F];
769 dirent->stat.mtime[3] = rdbuf[0x20];
770 dirent->stat.mtime[4] = rdbuf[0x21];
771 dirent->stat.mtime[5] = rdbuf[0x22];
772 dirent->stat.mtime[6] = rdbuf[0x23];
773 dirent->stat.mtime[7] = rdbuf[0x24];
775 dirent->stat.hisize = rdbuf[0x25] << 24;
776 dirent->stat.hisize |= rdbuf[0x26] << 16;
777 dirent->stat.hisize |= rdbuf[0x27] << 8;
778 dirent->stat.hisize |= rdbuf[0x28];
780 filename_len = rdbuf[0x29];
783 res = mmce_sio2_tx_rx_pio(0x0, filename_len, NULL, dirent->name, &timeout_1s);
785 DPRINTF(
"%s ERROR: P4 - Timedout waiting for /ACK\n", __func__);
791 res = mmce_sio2_tx_rx_pio(0x0, 0x3, NULL, rdbuf, &timeout_1s);
793 DPRINTF(
"%s ERROR: P5 - Timedout waiting for /ACK\n", __func__);
803int mmce_fs_getstat(iomanX_iop_file_t *file,
const char *name, iox_stat_t *stat)
810 u8 len = strlen(name) + 1;
812 DPRINTF(
"%s filename: %s\n", __func__, name);
814 mmce_fs_update_unit(file->unit);
816 wrbuf[0x0] = MMCE_ID;
817 wrbuf[0x1] = MMCE_CMD_FS_GETSTAT;
818 wrbuf[0x2] = MMCE_RESERVED;
823 res = mmce_sio2_tx_rx_pio(0x4, 0x4, wrbuf, rdbuf, &timeout_1s);
825 DPRINTF(
"%s ERROR: P1 - Timedout waiting for /ACK\n", __func__);
830 if (rdbuf[0x1] != MMCE_REPLY_CONST) {
831 DPRINTF(
"%s ERROR: Invalid response from card. Got 0x%x, Expected 0x%x\n", __func__, rdbuf[0x1], MMCE_REPLY_CONST);
837 res = mmce_sio2_tx_rx_pio(len, 0x0, name, NULL, &timeout_1s);
839 DPRINTF(
"%s ERROR: P2 - Timedout waiting for /ACK\n", __func__);
845 res = mmce_sio2_tx_rx_pio(0x0, 0x2b, NULL, rdbuf, &timeout_1s);
847 DPRINTF(
"%s ERROR: P4 - Timedout waiting for /ACK\n", __func__);
855 stat->mode = rdbuf[0x1] << 24;
856 stat->mode |= rdbuf[0x2] << 16;
857 stat->mode |= rdbuf[0x3] << 8;
858 stat->mode |= rdbuf[0x4];
860 stat->attr = rdbuf[0x5] << 24;
861 stat->attr |= rdbuf[0x6] << 16;
862 stat->attr |= rdbuf[0x7] << 8;
863 stat->attr |= rdbuf[0x8];
865 stat->size = rdbuf[0x9] << 24;
866 stat->size |= rdbuf[0xA] << 16;
867 stat->size |= rdbuf[0xB] << 8;
868 stat->size |= rdbuf[0xC];
870 stat->ctime[0] = rdbuf[0xD];
871 stat->ctime[1] = rdbuf[0xE];
872 stat->ctime[2] = rdbuf[0xF];
873 stat->ctime[3] = rdbuf[0x10];
874 stat->ctime[4] = rdbuf[0x11];
875 stat->ctime[5] = rdbuf[0x12];
876 stat->ctime[6] = rdbuf[0x13];
877 stat->ctime[7] = rdbuf[0x14];
879 stat->atime[0] = rdbuf[0x15];
880 stat->atime[1] = rdbuf[0x16];
881 stat->atime[2] = rdbuf[0x17];
882 stat->atime[3] = rdbuf[0x18];
883 stat->atime[4] = rdbuf[0x19];
884 stat->atime[5] = rdbuf[0x1A];
885 stat->atime[6] = rdbuf[0x1B];
886 stat->atime[7] = rdbuf[0x1C];
888 stat->mtime[0] = rdbuf[0x1D];
889 stat->mtime[1] = rdbuf[0x1E];
890 stat->mtime[2] = rdbuf[0x1F];
891 stat->mtime[3] = rdbuf[0x20];
892 stat->mtime[4] = rdbuf[0x21];
893 stat->mtime[5] = rdbuf[0x22];
894 stat->mtime[6] = rdbuf[0x23];
895 stat->mtime[7] = rdbuf[0x24];
897 stat->hisize = rdbuf[0x25] << 24;
898 stat->hisize |= rdbuf[0x26] << 16;
899 stat->hisize |= rdbuf[0x27] << 8;
900 stat->hisize |= rdbuf[0x28];
902 if (rdbuf[0x29] != 0) {
903 DPRINTF(
"Got bad return: %i\n", rdbuf[0x29]);
906 DPRINTF(
"Got good return\n");
912s64 mmce_fs_lseek64(iomanX_iop_file_t *file, s64 offset,
int whence)
920 DPRINTF(
"%s fd: %i, whence: %i\n", __func__, (u8)*(
int*)file->privdata, whence);
922 mmce_fs_update_unit(file->unit);
924 wrbuf[0x0] = MMCE_ID;
925 wrbuf[0x1] = MMCE_CMD_FS_LSEEK64;
926 wrbuf[0x2] = MMCE_RESERVED;
927 wrbuf[0x3] = (u8)(*(
int*)file->privdata);
929 wrbuf[0x4] = (offset & 0xFF00000000000000) >> 56;
930 wrbuf[0x5] = (offset & 0x00FF000000000000) >> 48;
931 wrbuf[0x6] = (offset & 0x0000FF0000000000) >> 40;
932 wrbuf[0x7] = (offset & 0x000000FF00000000) >> 32;
933 wrbuf[0x8] = (offset & 0x00000000FF000000) >> 24;
934 wrbuf[0x9] = (offset & 0x0000000000FF0000) >> 16;
935 wrbuf[0xa] = (offset & 0x000000000000FF00) >> 8;
936 wrbuf[0xb] = (offset & 0x00000000000000FF);
937 wrbuf[0xc] = (u8)(whence);
941 res = mmce_sio2_tx_rx_pio(0xd, 0x16, wrbuf, rdbuf, &timeout_1s);
944 DPRINTF(
"%s ERROR: P1 - Timedout waiting for /ACK\n", __func__);
948 if (rdbuf[0x1] != MMCE_REPLY_CONST) {
949 DPRINTF(
"%s ERROR: Invalid response from card. Got 0x%x, Expected 0x%x\n", __func__, rdbuf[0x1], MMCE_REPLY_CONST);
953 position = (s64)rdbuf[0xd] << 56;
954 position |= (s64)rdbuf[0xe] << 48;
955 position |= (s64)rdbuf[0xf] << 40;
956 position |= (s64)rdbuf[0x10] << 32;
957 position |= (s64)rdbuf[0x11] << 24;
958 position |= (s64)rdbuf[0x12] << 16;
959 position |= (s64)rdbuf[0x13] << 8;
960 position |= (s64)rdbuf[0x14];
965int mmce_fs_devctl(iomanX_iop_file_t *fd,
const char *name,
int cmd,
void *arg,
unsigned int arglen,
void *buf,
unsigned int buflen)
975 DPRINTF(
"%s cmd: %i, arglen, buflen: %i\n", __func__, cmd, arglen, buflen);
977 mmce_fs_update_unit(fd->unit);
981 res = mmce_cmd_ping();
984 case MMCE_CMD_GET_STATUS:
985 res = mmce_cmd_get_status();
988 case MMCE_CMD_GET_CARD:
989 res = mmce_cmd_get_card();
992 case MMCE_CMD_SET_CARD:
994 type = (args & 0xff000000) >> 24;
995 mode = (args & 0x00ff0000) >> 16;
996 num = (args & 0x0000ffff);
998 res = mmce_cmd_set_card(type, mode, num);
1001 case MMCE_CMD_GET_CHANNEL:
1002 res = mmce_cmd_get_channel();
1005 case MMCE_CMD_SET_CHANNEL:
1007 mode = (args & 0x00ff0000) >> 16;
1008 num = (args & 0x0000ffff);
1009 res = mmce_cmd_set_channel(mode, num);
1012 case MMCE_CMD_GET_GAMEID:
1013 res = mmce_cmd_get_gameid(buf);
1016 case MMCE_CMD_SET_GAMEID:
1017 char *str = (
char*)arg;
1018 res = mmce_cmd_set_gameid(str);
1021 case MMCE_CMD_RESET:
1022 res = mmce_cmd_reset();
1025 case MMCE_SETTINGS_ACK_WAIT_CYCLES:
1027 mmce_sio2_update_ack_wait_cycles(args);
1030 case MMCE_SETTINGS_SET_ALARMS:
1032 mmce_sio2_set_use_alarm(args);
1042int mmce_fs_ioctl2(iomanX_iop_file_t *file,
int cmd,
void *arg,
unsigned int arglen,
void *data,
unsigned int datalen)
1048 case MMCE_CMD_IOCTL_GET_FD:
1049 res = (u8)*(
int*)file->privdata;
1057static iomanX_iop_device_ops_t mmce_fio_ops =
1089static iomanX_iop_device_t mmce_dev =
1092 (IOP_DT_FS | IOP_DT_FSEXT),
1094 "Filesystem access mmce",
1098int mmce_fs_register(
void) {
1099 DPRINTF(
"Registering %s device\n", mmce_dev.name);
1100 iomanX_DelDrv(mmce_dev.name);
1102 if (iomanX_AddDrv(&mmce_dev)!= 0)
1108int mmce_fs_unregister(
void) {
1109 iomanX_DelDrv(mmce_dev.name);