s32 __MLoad_Ioctlv(u32 cmd, ioctlv *vector, u32 inlen, u32 iolen) { s32 ret = IPC_ENOENT; /* Invalidate cache */ InvalidateVector(vector, inlen, iolen); /* Check command */ switch (cmd) { case MLOAD_GET_IOS_INFO: { iosInfo *buffer = vector[0].data; /* Copy IOS info */ memcpy(buffer, &ios, sizeof(ios)); /* Success */ ret = 0; break; } case MLOAD_GET_MLOAD_VERSION: { /* Return MLOAD version */ ret = (MLOAD_VER << 4) | MLOAD_SUBVER; break; } case MLOAD_GET_LOAD_BASE: { u32 *address = (u32 *)vector[0].data; u32 *size = (u32 *)vector[1].data; /* Modules area info */ *address = (u32)exe_mem; *size = (u32)exe_mem_size; /* Success */ ret = 0; break; } case MLOAD_LOAD_ELF: { void *data = vector[0].data; /* Load ELF */ ret = Elf_Load(data); break; } case MLOAD_RUN_ELF: { /* Run ELF */ ret = Elf_Run(); break; } case MLOAD_RUN_THREAD: { u32 start = *(u32 *)vector[0].data; u32 stack = *(u32 *)vector[1].data; u32 slen = *(u32 *)vector[2].data; u32 prio = *(u32 *)vector[3].data; /* Run thread */ ret = Elf_RunThread((void *)start, NULL, (void *)stack, slen, prio); break; } case MLOAD_STOP_THREAD: { u32 tid = *(u32 *)vector[0].data; /* Stop thread */ ret = Elf_StopThread(tid); break; } case MLOAD_CONTINUE_THREAD: { u32 tid = *(u32 *)vector[0].data; /* Continue thread */ ret = Elf_ContinueThread(tid); break; } case MLOAD_MEMSET: { u32 addr = *(u32 *)vector[0].data; u32 val = *(u32 *)vector[1].data; u32 len = *(u32 *)vector[2].data; /* Invalidate cache */ os_sync_before_read((void *)addr, len); /* Do memset */ memset((void *)addr, val, len); /* Success */ ret = 0; break; } case MLOAD_SET_LOG_MODE: { u32 mode = *(u32 *)vector[0].data; /* Set debug mode */ ret = Debug_SetMode(mode); break; } case MLOAD_GET_LOG_BUFFER: { char *buffer = (char *)vector[0].data; u32 len = *(u32 *)vector[0].len; /* Get debug buffer */ ret = Debug_GetBuffer(buffer, len-1); break; } default: break; } /* Flush cache */ FlushVector(vector, inlen, iolen); return ret; }
s32 __FAT_Ioctlv(s32 fd, u32 cmd, ioctlv *vector, u32 inlen, u32 iolen) { s32 ret = IPC_EINVAL; /* Invalidate cache */ InvalidateVector(vector, inlen, iolen); /* Parse command */ switch (cmd) { /** Create directory **/ case IOCTL_FAT_MKDIR: { char *dirpath = (char *)vector[0].data; dbg_printf("FAT: IOCTL_FAT_MKDIR: fd = %d, dirpath = %s\n", fd, dirpath); /* Sart blinking */ Led_BlinkOn(); /* Create directory */ ret = FAT_CreateDir(dirpath); /* Stop blinking */ Led_BlinkOff(); dbg_printf("FAT: IOCTL_FAT_MKDIR: ret = %d\n", ret); break; } /** Create file **/ case IOCTL_FAT_MKFILE: { char *filepath = (char *)vector[0].data; dbg_printf("FAT: IOCTL_FAT_MKFILE: fd = %d, filepath = %s\n", fd, filepath); /* Sart blinking */ Led_BlinkOn(); /* Create file */ ret = FAT_CreateFile(filepath); /* Stop blinking */ Led_BlinkOff(); dbg_printf("FAT: IOCTL_FAT_MKFILE: ret = %d\n", ret); break; } /** Read directory **/ case IOCTL_FAT_READDIR_FS: case IOCTL_FAT_READDIR: { char *dirpath = (char *)vector[0].data; char *outbuf = NULL; u32 *outlen = NULL; u32 buflen = 0; u32 entries = 0, forFS; /* Set FS flag */ forFS = (cmd == IOCTL_FAT_READDIR_FS); dbg_printf("FAT: IOCTL_FAT_READDIR%s: fd = %d, dirpath = %s\n", forFS? "_FS" : "", fd, dirpath); /* Input values */ if (iolen > 1) { entries = *(u32 *)vector[1].data; outbuf = (char *)vector[2].data; outlen = (u32 *)vector[3].data; buflen = vector[2].len; } else outlen = (u32 *)vector[1].data; /* Read directory */ ret = FAT_ReadDir(dirpath, outbuf, buflen, outlen, entries, forFS); dbg_printf("FAT: IOCTL_FAT_READDIR%s: ret = %d\n", forFS? "_FS" : "", ret); break; } /** Delete object **/ case IOCTL_FAT_DELETE: { char *path = (char *)vector[0].data; dbg_printf("FAT: IOCTL_FAT_DELETE: fd = %d, path = %s\n", fd, path); /* Sart blinking */ Led_BlinkOn(); /* Delete file/directory */ ret = FAT_Delete(path); /* Stop blinking */ Led_BlinkOff(); dbg_printf("FAT: IOCTL_FAT_DELETE: ret = %d\n", ret); break; } /** Delete directory **/ case IOCTL_FAT_DELETEDIR: { char *dirpath = (char *)vector[0].data; dbg_printf("FAT: IOCTL_FAT_DELETEDIR: fd = %d, path = %s\n", fd, dirpath); /* Sart blinking */ Led_BlinkOn(); /* Delete directory */ ret = FAT_DeleteDir(dirpath); /* Stop blinking */ Led_BlinkOff(); dbg_printf("FAT: IOCTL_FAT_DELETEDIR: ret = %d\n", ret); break; } /** Rename object **/ case IOCTL_FAT_RENAME: { char *oldname = (char *)vector[0].data; char *newname = (char *)vector[1].data; dbg_printf("FAT: IOCTL_FAT_RENAME: fd = %d, from = %s, to = %s\n", fd, oldname, newname); /* Sart blinking */ Led_BlinkOn(); /* Rename object */ ret = FAT_Rename(oldname, newname); /* Stop blinking */ Led_BlinkOff(); dbg_printf("FAT: IOCTL_FAT_RENAME: ret = %d\n", ret); break; } /** Get stats **/ case IOCTL_FAT_STATS: { char *path = (char *)vector[0].data; void *stats = (void *)vector[1].data; dbg_printf("FAT: IOCTL_FAT_STATS: fd = %d, path = %s\n", fd, path); /* Get stats */ ret = FAT_GetStats(path, stats); dbg_printf("FAT: IOCTL_FAT_STATS: ret = %d, size = %d\n", ret, ((struct stats *)stats)->size); break; } /** Get usage **/ case IOCTL_FAT_GETUSAGE_FS: case IOCTL_FAT_GETUSAGE: { char *path = (char *)vector[0].data; u64 *size = (u64 *)vector[1].data; u32 *files = (u32 *)vector[2].data; u32 *dirs = (u32 *)vector[3].data; u32 fakedirs, fakefiles, forFS; /* Set default pointers */ if (iolen < 2) files = &fakefiles; if (iolen < 3) dirs = &fakedirs; /* Set initial values */ *size = 0; *files = 0; *dirs = 0; /* Set FS flag */ forFS = (cmd == IOCTL_FAT_GETUSAGE_FS); dbg_printf("FAT: IOCTL_FAT_GETUSAGE%s: fd = %d, path = %s\n", forFS?"_FS":"", fd, path); /* Get usage */ ret = FAT_GetUsage(path, size, files, dirs, forFS); dbg_printf("FAT: IOCTL_FAT_GETUSAGE: ret = %d, size = %dl, files = %d, dirs = %d\n", ret, *size, *files, *dirs); break; } /** Mount SD card **/ case IOCTL_FAT_MOUNT_SD: { s32 partition = inlen > 0 ? *(s32 *)vector[0].data : -1; /* Mount SD card */ ret = FAT_Mount(0, partition); break; } /** Unmount SD card **/ case IOCTL_FAT_UMOUNT_SD: { /* Unmount SD card */ ret = FAT_Unmount(0); if (ret < 0) break; /* Deinitialize SDIO */ ret = sdio_Shutdown(); if (!ret) ret = IPC_EINVAL; break; } /** Mount USB device **/ case IOCTL_FAT_MOUNT_USB: { s32 partition = inlen > 0 ? *(s32 *)vector[0].data : -1; /* Mount USB device */ ret = FAT_Mount(1, partition); break; } /** Unmount USB card **/ case IOCTL_FAT_UMOUNT_USB: { /* Unmount USB */ ret = FAT_Unmount(1); if (ret < 0) break; /* Deinitialize USB */ ret = usbstorage_Shutdown(); if (!ret) ret = IPC_EINVAL; break; } /** Get mounted partition of the given device **/ case IOCTL_FAT_GETPARTITION: { u32 device = *(u32 *)vector[0].data; u32 *partition = (u32 *)vector[1].data; /* Get partition */ ret = FAT_GetPartition(device, partition); break; } default: break; } /* Flush cache */ FlushVector(vector, inlen, iolen); return ret; }
s32 __SDHC_Ioctlv(u32 cmd, ioctlv *vector, u32 inlen, u32 iolen) { s32 ret = IPC_EINVAL; /* Invalidate cache */ InvalidateVector(vector, inlen, iolen); /* Parse IOCTLV command */ switch (cmd) { /** Initialize SDHC **/ case IOCTL_SDHC_INIT: { /* Initialize SDIO */ ret = !sdio_Startup(); break; } /** Read sectors **/ case IOCTL_SDHC_READ: { u32 sector = *(u32 *)(vector[0].data); u32 numSectors = *(u32 *)(vector[1].data); void *buffer = vector[2].data; /* Read sectors */ ret = !sdio_ReadSectors(sector, numSectors, buffer); break; } /** Write sectors **/ case IOCTL_SDHC_WRITE: { u32 sector = *(u32 *)(vector[0].data); u32 numSectors = *(u32 *)(vector[1].data); void *buffer = vector[2].data; /* Write sectors */ ret = !sdio_WriteSectors(sector, numSectors, buffer); break; } /** Check for SD card **/ case IOCTL_SDHC_ISINSERTED: { /* Check if SD card is inserted */ ret = !sdio_IsInserted(); break; } /** Open WBFS disc **/ case IOCTL_WBFS_OPEN_DISC: { u8 *discid = (u8 *)(vector[0].data); /* Open WBFS disc */ ret = WBFS_OpenDisc(discid); break; } /** Read WBFS disc **/ case IOCTL_WBFS_READ_DISC: { u32 offset = *(u32 *)(vector[0].data); u32 len = *(u32 *)(vector[1].data); void *buffer = vector[2].data; /* Read WBFS disc */ ret = WBFS_Read(buffer, len, offset); if (ret) ret = 0x8000; break; } default: break; } /* Flush cache */ FlushVector(vector, inlen, iolen); return ret; }
s32 FAT_Ioctlv(s32 fd, u32 cmd, ioctlv *vector, u32 inlen, u32 iolen) { s32 ret = IPC_EINVAL; /* Invalidate ache */ InvalidateVector(vector, inlen, iolen); /* Parse command */ switch (cmd) { /** Create directory **/ case IOCTL_FAT_MKDIR: { char *dirpath = (char *)vector[0].data; /* Create directory */ ret = FAT_CreateDir(dirpath); break; } /** Create file **/ case IOCTL_FAT_MKFILE: { char *filepath = (char *)vector[0].data; /* Create file */ ret = FAT_CreateFile(filepath); break; } /** Read directory **/ case IOCTL_FAT_READDIR: { char *dirpath = (char *)vector[0].data; char *outbuf = NULL; u32 *outlen = NULL; u32 buflen = 0; u32 entries = 0; /* Input values */ if (iolen > 1) { entries = *(u32 *)vector[1].data; outbuf = (char *)vector[2].data; outlen = (u32 *)vector[3].data; buflen = vector[2].len; } else outlen = (u32 *)vector[1].data; /* Clear buffer */ if (outbuf) memset(outbuf, 0, buflen); /* Read directory */ ret = FAT_ReadDir(dirpath, outbuf, outlen, entries); break; } /** Read directory (LFN) **/ case IOCTL_FAT_READDIR_LFN: { char *dirpath = (char *)vector[0].data; char *outbuf = NULL; u32 *outlen = NULL; u32 buflen = 0; u32 entries = 0; /* Input values */ if (iolen > 1) { entries = *(u32 *)vector[1].data; outbuf = (char *)vector[2].data; outlen = (u32 *)vector[3].data; buflen = vector[2].len; } else outlen = (u32 *)vector[1].data; /* Clear buffer */ if (outbuf) memset(outbuf, 0, buflen); /* Read directory (LFN) */ ret = FAT_ReadDirLfn(dirpath, outbuf, outlen, entries); break; } /** Delete object **/ case IOCTL_FAT_DELETE: { char *path = (char *)vector[0].data; /* Delete file/directory */ ret = FAT_Delete(path); break; } /** Delete directory **/ case IOCTL_FAT_DELETEDIR: { char *dirpath = (char *)vector[0].data; /* Delete directory */ ret = FAT_DeleteDir(dirpath); break; } /** Rename object **/ case IOCTL_FAT_RENAME: { char *oldname = (char *)vector[0].data; char *newname = (char *)vector[1].data; /* Rename file/directory */ ret = FAT_Rename(oldname, newname); break; } /** Get stats **/ case IOCTL_FAT_STAT: { char *path = (char *)vector[0].data; void *stats = vector[1].data; /* Get stats */ ret = FAT_Stat(path, stats); break; } /** Get filesystem stats **/ case IOCTL_FAT_VFSSTATS: { char *path = (char *)vector[0].data; void *stats = vector[1].data; /* Get filesystem stats */ ret = FAT_GetVfsStats(path, stats); break; } /** Get usage **/ case IOCTL_FAT_GETUSAGE: { char *path = (char *)vector[0].data; u32 *blocks = (u32 *)vector[1].data; u32 *inodes = (u32 *)vector[2].data; u64 size; /* Reset values */ *blocks = 0; *inodes = 0; /* Get usage */ ret = FAT_GetUsage(path, &size, inodes); /* Not a directory */ if (ret == -ENOTDIR) { ret = 0; break; } /* Calculate blocks */ *blocks = (size / 0x4000); break; } /** Mount SD card **/ case IOCTL_FAT_MOUNTSD: { /* Initialize SDIO */ ret = !__io_wiisd.startup(); if (ret) break; /* Mount SD card */ ret = !fatMountSimple("sd", &__io_wiisd); break; } /** Unmount SD card **/ case IOCTL_FAT_UMOUNTSD: { /* Unmount SD card */ fatUnmount("sd"); /* Deinitialize SDIO */ ret = !__io_wiisd.shutdown(); break; } /** Mount USB card **/ case IOCTL_FAT_MOUNTUSB: { /* Initialize USB */ ret = !__io_usbstorage.startup(); if (ret) break; /* Mount USB */ ret = !fatMountSimple("usb", &__io_usbstorage); break; } /** Unmount USB card **/ case IOCTL_FAT_UMOUNTUSB: { /* Unmount USB */ fatUnmount("usb"); /* Deinitialize USB */ ret = !__io_usbstorage.shutdown(); break; } default: break; } /* Flush cache */ FlushVector(vector, inlen, iolen); return ret; }