2010-12-12 17:31:13 +01:00
|
|
|
#include <ogcsys.h>
|
|
|
|
#include <malloc.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "usbloader/sdhc.h"
|
|
|
|
#include "usbloader/usbstorage2.h"
|
|
|
|
#include "usbloader/wdvd.h"
|
|
|
|
#include "wbfs_rw.h"
|
|
|
|
|
|
|
|
/* Constants */
|
|
|
|
#define MAX_NB_SECTORS 32
|
|
|
|
|
|
|
|
rw_sector_callback_t readCallback = NULL;
|
|
|
|
rw_sector_callback_t writeCallback = NULL;
|
|
|
|
|
|
|
|
s32 __ReadDVD(void *fp, u32 lba, u32 len, void *iobuf)
|
|
|
|
{
|
|
|
|
void *buffer = NULL;
|
|
|
|
|
|
|
|
u64 offset;
|
|
|
|
u32 mod, size;
|
|
|
|
s32 ret;
|
|
|
|
|
|
|
|
/* Calculate offset */
|
|
|
|
offset = ((u64) lba) << 2;
|
|
|
|
|
|
|
|
/* Calcualte sizes */
|
|
|
|
mod = len % 32;
|
|
|
|
size = len - mod;
|
|
|
|
|
|
|
|
/* Read aligned data */
|
|
|
|
if (size)
|
|
|
|
{
|
|
|
|
ret = WDVD_UnencryptedRead(iobuf, size, offset);
|
|
|
|
if (ret < 0) goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Read non-aligned data */
|
|
|
|
if (mod)
|
|
|
|
{
|
|
|
|
/* Allocate memory */
|
|
|
|
buffer = memalign(32, 0x20);
|
|
|
|
if (!buffer) return -1;
|
|
|
|
|
|
|
|
/* Read data */
|
|
|
|
ret = WDVD_UnencryptedRead(buffer, 0x20, offset + size);
|
|
|
|
if (ret < 0) goto out;
|
|
|
|
|
|
|
|
/* Copy data */
|
|
|
|
void *ptr = ((u8 *) iobuf) + size;
|
|
|
|
memcpy(ptr, buffer, mod);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Success */
|
|
|
|
ret = 0;
|
|
|
|
|
|
|
|
out:
|
|
|
|
/* Free memory */
|
|
|
|
if (buffer) free(buffer);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
s32 __ReadUSB(void *fp, u32 lba, u32 count, void *iobuf)
|
|
|
|
{
|
2011-01-28 22:19:43 +01:00
|
|
|
WBFS_PartInfo * info = (WBFS_PartInfo *) fp;
|
2010-12-12 17:31:13 +01:00
|
|
|
u32 cnt = 0;
|
|
|
|
s32 ret;
|
2011-01-28 22:19:43 +01:00
|
|
|
u32 partition_offset = info->partition_lba + (lba-info->partition_lba)*(info->wbfs_sector_size/info->hdd_sector_size);
|
2011-02-04 16:25:27 +01:00
|
|
|
count *= (info->wbfs_sector_size/info->hdd_sector_size);
|
2010-12-12 17:31:13 +01:00
|
|
|
|
|
|
|
/* Do reads */
|
|
|
|
while (cnt < count)
|
|
|
|
{
|
2011-02-04 16:25:27 +01:00
|
|
|
u8 *ptr = ((u8 *) iobuf) + (cnt * info->hdd_sector_size);
|
2010-12-12 17:31:13 +01:00
|
|
|
u32 sectors = (count - cnt);
|
|
|
|
|
|
|
|
/* Read sectors is too big */
|
|
|
|
if (sectors > MAX_NB_SECTORS) sectors = MAX_NB_SECTORS;
|
|
|
|
|
|
|
|
/* USB read */
|
2011-06-22 19:57:37 +02:00
|
|
|
ret = info->handle->readSectors(partition_offset + cnt, sectors, ptr);
|
2011-01-12 20:30:04 +01:00
|
|
|
if (!ret) return -1;
|
2010-12-12 17:31:13 +01:00
|
|
|
|
|
|
|
/* Increment counter */
|
|
|
|
cnt += sectors;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
s32 __WriteUSB(void *fp, u32 lba, u32 count, void *iobuf)
|
|
|
|
{
|
2011-01-28 22:19:43 +01:00
|
|
|
WBFS_PartInfo * info = (WBFS_PartInfo *) fp;
|
2010-12-12 17:31:13 +01:00
|
|
|
u32 cnt = 0;
|
|
|
|
s32 ret;
|
2011-01-28 22:19:43 +01:00
|
|
|
u32 partition_offset = info->partition_lba + (lba-info->partition_lba)*(info->wbfs_sector_size/info->hdd_sector_size);
|
2011-02-04 16:25:27 +01:00
|
|
|
count *= (info->wbfs_sector_size/info->hdd_sector_size);
|
2010-12-12 17:31:13 +01:00
|
|
|
|
|
|
|
/* Do writes */
|
|
|
|
while (cnt < count)
|
|
|
|
{
|
2011-02-04 16:25:27 +01:00
|
|
|
u8 *ptr = ((u8 *) iobuf) + (cnt * info->hdd_sector_size);
|
2010-12-12 17:31:13 +01:00
|
|
|
u32 sectors = (count - cnt);
|
|
|
|
|
|
|
|
/* Write sectors is too big */
|
|
|
|
if (sectors > MAX_NB_SECTORS) sectors = MAX_NB_SECTORS;
|
|
|
|
|
|
|
|
/* USB write */
|
2011-06-22 19:57:37 +02:00
|
|
|
ret = info->handle->writeSectors(partition_offset + cnt, sectors, ptr);
|
2011-01-12 20:30:04 +01:00
|
|
|
if (!ret) return -1;
|
2010-12-12 17:31:13 +01:00
|
|
|
|
|
|
|
/* Increment counter */
|
|
|
|
cnt += sectors;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
s32 __ReadSDHC(void *fp, u32 lba, u32 count, void *iobuf)
|
|
|
|
{
|
2011-01-28 22:19:43 +01:00
|
|
|
WBFS_PartInfo * info = (WBFS_PartInfo *) fp;
|
2010-12-12 17:31:13 +01:00
|
|
|
u32 cnt = 0;
|
|
|
|
s32 ret;
|
2011-01-28 22:19:43 +01:00
|
|
|
u32 partition_offset = info->partition_lba + (lba-info->partition_lba)*(info->wbfs_sector_size/info->hdd_sector_size);
|
|
|
|
count *= info->wbfs_sector_size/info->hdd_sector_size;
|
2010-12-12 17:31:13 +01:00
|
|
|
|
|
|
|
/* Do reads */
|
|
|
|
while (cnt < count)
|
|
|
|
{
|
2011-01-28 22:19:43 +01:00
|
|
|
void *ptr = ((u8 *) iobuf) + (cnt * info->wbfs_sector_size);
|
2010-12-12 17:31:13 +01:00
|
|
|
u32 sectors = (count - cnt);
|
|
|
|
|
|
|
|
/* Read sectors is too big */
|
|
|
|
if (sectors > MAX_NB_SECTORS) sectors = MAX_NB_SECTORS;
|
|
|
|
|
|
|
|
/* SDHC read */
|
2011-01-28 22:19:43 +01:00
|
|
|
ret = SDHC_ReadSectors(partition_offset + cnt, sectors, ptr);
|
2010-12-12 17:31:13 +01:00
|
|
|
if (!ret) return -1;
|
|
|
|
|
|
|
|
/* Increment counter */
|
|
|
|
cnt += sectors;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
s32 __WriteSDHC(void *fp, u32 lba, u32 count, void *iobuf)
|
|
|
|
{
|
2011-01-28 22:19:43 +01:00
|
|
|
WBFS_PartInfo * info = (WBFS_PartInfo *) fp;
|
2010-12-12 17:31:13 +01:00
|
|
|
u32 cnt = 0;
|
|
|
|
s32 ret;
|
2011-01-28 22:19:43 +01:00
|
|
|
u32 partition_offset = info->partition_lba + (lba-info->partition_lba)*(info->wbfs_sector_size/info->hdd_sector_size);
|
|
|
|
count *= info->wbfs_sector_size/info->hdd_sector_size;
|
2010-12-12 17:31:13 +01:00
|
|
|
|
|
|
|
/* Do writes */
|
|
|
|
while (cnt < count)
|
|
|
|
{
|
2011-01-28 22:19:43 +01:00
|
|
|
void *ptr = ((u8 *) iobuf) + (cnt * info->wbfs_sector_size);
|
2010-12-12 17:31:13 +01:00
|
|
|
u32 sectors = (count - cnt);
|
|
|
|
|
|
|
|
/* Write sectors is too big */
|
|
|
|
if (sectors > MAX_NB_SECTORS) sectors = MAX_NB_SECTORS;
|
|
|
|
|
|
|
|
/* SDHC write */
|
2011-01-28 22:19:43 +01:00
|
|
|
ret = SDHC_WriteSectors(partition_offset + cnt, sectors, ptr);
|
2010-12-12 17:31:13 +01:00
|
|
|
if (!ret) return -1;
|
|
|
|
|
|
|
|
/* Increment counter */
|
|
|
|
cnt += sectors;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|