wiiu-nanddumper-payload/ios_fs/source/sdio.c

108 lines
2.7 KiB
C

#include "types.h"
#include "imports.h"
static int sdcard_access_mutex = 0;
static u32 dumpdata_offset = 0;
typedef struct _sd_command_block_t
{
u32 cnt;
u32 block_size;
u32 command_type;
void * data_ptr;
u64 offset;
void *callback;
void *callback_arg;
int minus_one;
} __attribute__((packed)) sd_command_block_t;
void sdcard_init(void)
{
// this should run *after* /dev/mmc thread is created
// first we create our synchronization stuff
sdcard_access_mutex = FS_SVC_CREATEMUTEX(1, 1);
dumpdata_offset = 0;
// then we sleep until /dev/mmc is done initializing sdcard (TODO : better synchronization here)
FS_SLEEP(1000);
// finally we set some flags to indicate sdcard is ready for use
FS_MMC_SDCARD_STRUCT[0x24/4] = FS_MMC_SDCARD_STRUCT[0x24/4] | 0x20;
FS_MMC_SDCARD_STRUCT[0x28/4] = FS_MMC_SDCARD_STRUCT[0x28/4] & (~0x04);
}
static void sdcard_readwrite_callback(void *priv_data, int result)
{
int *private_data = (int*)priv_data;
private_data[1] = result;
FS_SVC_RELEASEMUTEX(private_data[0]);
}
void sdcard_lock_mutex(void)
{
FS_SVC_ACQUIREMUTEX(sdcard_access_mutex, 0);
}
void sdcard_unlock_mutex(void)
{
FS_SVC_RELEASEMUTEX(sdcard_access_mutex);
}
int sdcard_readwrite(int is_read, void *data, u32 cnt, u32 block_size, u32 offset_blocks, int * out_callback_arg, int device_id)
{
// first of all, grab sdcard mutex
sdcard_lock_mutex();
//also create a mutex for synchronization with end of operation...
int sync_mutex = FS_SVC_CREATEMUTEX(1, 1);
// ...and acquire it
FS_SVC_ACQUIREMUTEX(sync_mutex, 0);
// block_size needs to be equal to sector_size (0x200)
while(block_size > 0x200)
{
block_size >>= 1;
cnt <<= 1;
offset_blocks <<= 1;
}
// build rw command paramstruct
sd_command_block_t command;
command.cnt = cnt;
command.block_size = block_size;
command.command_type = (is_read ? 0x03 : 0x00);
command.data_ptr = data;
command.offset = offset_blocks;
command.callback = 0x00;
command.callback_arg = 0x00;
command.minus_one = (u32)-1;
// setup parameters
int private_data[2];
private_data[0] = sync_mutex;
private_data[1] = 0;
// call readwrite function
int result = FS_SDIO_DOREADWRITECOMMAND(device_id, &command, offset_blocks, sdcard_readwrite_callback, (void*)private_data);
if(result == 0)
{
// wait for callback to give the go-ahead
FS_SVC_ACQUIREMUTEX(sync_mutex, 0);
if(out_callback_arg)
{
*out_callback_arg = private_data[1];
}
}
// finally, release sdcard mutexes
FS_SVC_DESTROYMUTEX(sync_mutex);
sdcard_unlock_mutex();
return result;
}