-added custom sd card ogc file like we did with usb already

-proper cleaning the memory now for the devices so a ios
reload will work just fine without breaking sd/usb io
This commit is contained in:
fix94.1 2013-01-19 18:32:46 +00:00
parent 8fbd49ab7d
commit b700d056b8
6 changed files with 690 additions and 24 deletions

View File

@ -27,11 +27,11 @@
#include <ogc/mutex.h> #include <ogc/mutex.h>
#include <ogc/system.h> #include <ogc/system.h>
#include <sdcard/gcsd.h> #include <sdcard/gcsd.h>
#include <sdcard/wiisd_io.h>
#include "DeviceHandler.hpp" #include "DeviceHandler.hpp"
#include "fat.h" #include "fat.h"
#include "sdhc.h"
#include "usbthread.h" #include "usbthread.h"
#include "sdhc.h"
#include "wiisd_libogc.h"
#include "usbstorage.h" #include "usbstorage.h"
#include "usbstorage_libogc.h" #include "usbstorage_libogc.h"
#include "loader/cios.h" #include "loader/cios.h"
@ -332,7 +332,7 @@ void DeviceHandler::WaitForDevice(const DISC_INTERFACE *Handle)
bool DeviceHandler::MountDevolution() bool DeviceHandler::MountDevolution()
{ {
int NewPartition = (currentPartition == SD ? currentPartition : currentPartition - 1); int NewPartition = (currentPartition == SD ? currentPartition : currentPartition - 1);
const DISC_INTERFACE *handle = (currentPartition == SD) ? &__io_wiisd : &__io_usbstorage_ogc; const DISC_INTERFACE *handle = (currentPartition == SD) ? &__io_wiisd_ogc : &__io_usbstorage_ogc;
/* We need to wait for the device to get ready for a remount */ /* We need to wait for the device to get ready for a remount */
WaitForDevice(handle); WaitForDevice(handle);
/* Only mount the partition we need */ /* Only mount the partition we need */

View File

@ -2,9 +2,9 @@
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <ogcsys.h> #include <ogcsys.h>
#include <sdcard/wiisd_io.h>
#include "memory/mem2.hpp"
#include "sdhc.h" #include "sdhc.h"
#include "wiisd_libogc.h"
#include "memory/mem2.hpp"
/* IOCTL comamnds */ /* IOCTL comamnds */
#define IOCTL_SDHC_INIT 0x01 #define IOCTL_SDHC_INIT 0x01
@ -23,7 +23,7 @@ static char fs[] ATTRIBUTE_ALIGN(32) = "/dev/sdio/sdhc";
static s32 hid = -1, fd = -1; static s32 hid = -1, fd = -1;
static u32 sector_size = SDHC_SECTOR_SIZE; static u32 sector_size = SDHC_SECTOR_SIZE;
static void *sdhc_buf2; static void *sdhc_buf2 = NULL;
bool SDHC_Init(void) bool SDHC_Init(void)
{ {
@ -33,7 +33,7 @@ bool SDHC_Init(void)
if (sdhc_mode_sd) if (sdhc_mode_sd)
{ {
sdhc_inited = __io_wiisd.startup(); sdhc_inited = __io_wiisd_ogc.startup();
return sdhc_inited; return sdhc_inited;
} }
@ -46,10 +46,8 @@ bool SDHC_Init(void)
// allocate buf2 // allocate buf2
if(sdhc_buf2 == NULL) if(sdhc_buf2 == NULL)
{
sdhc_buf2 = MEM2_lo_alloc(SDHC_MEM2_SIZE); sdhc_buf2 = MEM2_lo_alloc(SDHC_MEM2_SIZE);
if(sdhc_buf2 == NULL) goto err; if(sdhc_buf2 == NULL) goto err;
}
/* Open SDHC device */ /* Open SDHC device */
fd = IOS_Open(fs, 0); fd = IOS_Open(fs, 0);
@ -76,15 +74,17 @@ err:
bool SDHC_Close(void) bool SDHC_Close(void)
{ {
sdhc_inited = 0; sdhc_inited = 0;
if (sdhc_mode_sd) { if(sdhc_mode_sd)
return __io_wiisd.shutdown(); return __io_wiisd_ogc.shutdown();
}
/* Close SDHC device */ /* Close SDHC device */
if(fd >= 0) { if(fd >= 0) {
IOS_Close(fd); IOS_Close(fd);
fd = -1; fd = -1;
} }
if(sdhc_buf2 != NULL)
MEM2_lo_free(sdhc_buf2);
sdhc_buf2 = NULL;
return true; return true;
} }
@ -92,9 +92,8 @@ bool SDHC_Close(void)
bool SDHC_IsInserted(void) bool SDHC_IsInserted(void)
{ {
s32 ret; s32 ret;
if (sdhc_mode_sd) { if(sdhc_mode_sd)
return __io_wiisd.isInserted(); return __io_wiisd_ogc.isInserted();
}
/* Check if SD card is inserted */ /* Check if SD card is inserted */
ret = IOS_IoctlvFormat(hid, fd, IOCTL_SDHC_ISINSERTED, ":"); ret = IOS_IoctlvFormat(hid, fd, IOCTL_SDHC_ISINSERTED, ":");
@ -105,7 +104,7 @@ bool SDHC_IsInserted(void)
bool SDHC_ReadSectors(u32 sector, u32 count, void *buffer) bool SDHC_ReadSectors(u32 sector, u32 count, void *buffer)
{ {
if(sdhc_mode_sd) if(sdhc_mode_sd)
return __io_wiisd.readSectors(sector, count, buffer); return __io_wiisd_ogc.readSectors(sector, count, buffer);
u32 size; u32 size;
s32 ret = -1; s32 ret = -1;
@ -156,7 +155,7 @@ bool SDHC_ReadSectors(u32 sector, u32 count, void *buffer)
bool SDHC_WriteSectors(u32 sector, u32 count, void *buffer) bool SDHC_WriteSectors(u32 sector, u32 count, void *buffer)
{ {
if(sdhc_mode_sd) if(sdhc_mode_sd)
return __io_wiisd.writeSectors(sector, count, buffer); return __io_wiisd_ogc.writeSectors(sector, count, buffer);
u32 size; u32 size;
s32 ret = -1; s32 ret = -1;

View File

@ -128,6 +128,9 @@ void USBStorage2_Deinit()
} }
else if(fd >= 0) else if(fd >= 0)
IOS_Close(fd); // not sure to close the fd is needed IOS_Close(fd); // not sure to close the fd is needed
if(mem2_ptr != NULL)
MEM2_lo_free(mem2_ptr);
mem2_ptr = NULL;
/* Reset Variables */ /* Reset Variables */
if(usb2_port == 0 || usb2_port == 1) if(usb2_port == 0 || usb2_port == 1)

View File

@ -207,9 +207,11 @@ s32 USBStorage_OGC_Initialize()
_CPU_ISR_Disable(level); _CPU_ISR_Disable(level);
LWP_InitQueue(&__usbstorage_ogc_waitq); LWP_InitQueue(&__usbstorage_ogc_waitq);
if(!arena_ptr) { if(arena_ptr == NULL)
arena_ptr = (u8*)MEM2_lo_alloc(HEAP_SIZE); arena_ptr = (u8*)MEM2_lo_alloc(HEAP_SIZE);
} if(arena_ptr == NULL)
return IPC_ENOMEM;
__lwp_heap_init(&__heap, arena_ptr, HEAP_SIZE, 32); __lwp_heap_init(&__heap, arena_ptr, HEAP_SIZE, 32);
cbw_buffer=(u8*)__lwp_heap_allocate(&__heap, 32); cbw_buffer=(u8*)__lwp_heap_allocate(&__heap, 32);
__inited = true; __inited = true;
@ -949,6 +951,9 @@ static bool __usbstorage_ogc_Shutdown(void)
{ {
if (__vid != 0 || __pid != 0) if (__vid != 0 || __pid != 0)
USBStorage_OGC_Close(&__usbfd); USBStorage_OGC_Close(&__usbfd);
if(arena_ptr != NULL)
MEM2_lo_free(arena_ptr);
arena_ptr = NULL;
return true; return true;
} }

View File

@ -0,0 +1,615 @@
/*
wiisd.c
Hardware routines for reading and writing to the Wii's internal
SD slot.
Copyright (c) 2008
Michael Wiedenbauer (shagkur)
Dave Murphy (WinterMute)
Sven Peter <svpe@gmx.net>
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(HW_RVL)
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <gcutil.h>
#include <ogc/ipc.h>
#include <unistd.h>
#include <ogc/disc_io.h>
#include "wiisd_libogc.h"
#include "memory/mem2.hpp"
#include <ogc/machine/asm.h>
#include <ogc/machine/processor.h>
#define SDIO_HEAPSIZE (5*1024)
#define PAGE_SIZE512 512
#define SDIOHCR_RESPONSE 0x10
#define SDIOHCR_HOSTCONTROL 0x28
#define SDIOHCR_POWERCONTROL 0x29
#define SDIOHCR_CLOCKCONTROL 0x2c
#define SDIOHCR_TIMEOUTCONTROL 0x2e
#define SDIOHCR_SOFTWARERESET 0x2f
#define SDIOHCR_HOSTCONTROL_4BIT 0x02
#define SDIO_DEFAULT_TIMEOUT 0xe
#define IOCTL_SDIO_WRITEHCREG 0x01
#define IOCTL_SDIO_READHCREG 0x02
#define IOCTL_SDIO_READCREG 0x03
#define IOCTL_SDIO_RESETCARD 0x04
#define IOCTL_SDIO_WRITECREG 0x05
#define IOCTL_SDIO_SETCLK 0x06
#define IOCTL_SDIO_SENDCMD 0x07
#define IOCTL_SDIO_SETBUSWIDTH 0x08
#define IOCTL_SDIO_READMCREG 0x09
#define IOCTL_SDIO_WRITEMCREG 0x0A
#define IOCTL_SDIO_GETSTATUS 0x0B
#define IOCTL_SDIO_GETOCR 0x0C
#define IOCTL_SDIO_READDATA 0x0D
#define IOCTL_SDIO_WRITEDATA 0x0E
#define SDIOCMD_TYPE_BC 1
#define SDIOCMD_TYPE_BCR 2
#define SDIOCMD_TYPE_AC 3
#define SDIOCMD_TYPE_ADTC 4
#define SDIO_RESPONSE_NONE 0
#define SDIO_RESPONSE_R1 1
#define SDIO_RESPONSE_R1B 2
#define SDIO_RESPOSNE_R2 3
#define SDIO_RESPONSE_R3 4
#define SDIO_RESPONSE_R4 5
#define SDIO_RESPONSE_R5 6
#define SDIO_RESPONSE_R6 7
#define SDIO_CMD_GOIDLE 0x00
#define SDIO_CMD_ALL_SENDCID 0x02
#define SDIO_CMD_SENDRCA 0x03
#define SDIO_CMD_SELECT 0x07
#define SDIO_CMD_DESELECT 0x07
#define SDIO_CMD_SENDIFCOND 0x08
#define SDIO_CMD_SENDCSD 0x09
#define SDIO_CMD_SENDCID 0x0A
#define SDIO_CMD_SENDSTATUS 0x0D
#define SDIO_CMD_SETBLOCKLEN 0x10
#define SDIO_CMD_READBLOCK 0x11
#define SDIO_CMD_READMULTIBLOCK 0x12
#define SDIO_CMD_WRITEBLOCK 0x18
#define SDIO_CMD_WRITEMULTIBLOCK 0x19
#define SDIO_CMD_APPCMD 0x37
#define SDIO_ACMD_SETBUSWIDTH 0x06
#define SDIO_ACMD_SENDSCR 0x33
#define SDIO_ACMD_SENDOPCOND 0x29
#define SDIO_STATUS_CARD_INSERTED 0x1
#define SDIO_STATUS_CARD_INITIALIZED 0x10000
#define SDIO_STATUS_CARD_SDHC 0x100000
#define READ_BL_LEN ((u8)(__sd0_csd[5]&0x0f))
#define WRITE_BL_LEN ((u8)(((__sd0_csd[12]&0x03)<<2)|((__sd0_csd[13]>>6)&0x03)))
static u8 *rw_buffer = NULL;
struct _sdiorequest
{
u32 cmd;
u32 cmd_type;
u32 rsp_type;
u32 arg;
u32 blk_cnt;
u32 blk_size;
void *dma_addr;
u32 isdma;
u32 pad0;
};
struct _sdioresponse
{
u32 rsp_fields[3];
u32 acmd12_response;
};
static s32 __sd0_fd = -1;
static u16 __sd0_rca = 0;
static s32 __sd0_initialized = 0;
static s32 __sd0_sdhc = 0;
//static u8 __sd0_csd[16];
static u8 __sd0_cid[16];
static s32 __sdio_initialized = 0;
static char _sd0_fs[] ATTRIBUTE_ALIGN(32) = "/dev/sdio/slot0";
static s32 __sdio_sendcommand(u32 cmd,u32 cmd_type,u32 rsp_type,u32 arg,u32 blk_cnt,u32 blk_size,void *buffer,void *reply,u32 rlen)
{
s32 ret;
STACK_ALIGN(ioctlv,iovec,3,32);
STACK_ALIGN(struct _sdiorequest,request,1,32);
STACK_ALIGN(struct _sdioresponse,response,1,32);
request->cmd = cmd;
request->cmd_type = cmd_type;
request->rsp_type = rsp_type;
request->arg = arg;
request->blk_cnt = blk_cnt;
request->blk_size = blk_size;
request->dma_addr = buffer;
request->isdma = ((buffer!=NULL)?1:0);
request->pad0 = 0;
if(request->isdma || __sd0_sdhc == 1) {
iovec[0].data = request;
iovec[0].len = sizeof(struct _sdiorequest);
iovec[1].data = buffer;
iovec[1].len = (blk_size*blk_cnt);
iovec[2].data = response;
iovec[2].len = sizeof(struct _sdioresponse);
ret = IOS_Ioctlv(__sd0_fd,IOCTL_SDIO_SENDCMD,2,1,iovec);
} else
ret = IOS_Ioctl(__sd0_fd,IOCTL_SDIO_SENDCMD,request,sizeof(struct _sdiorequest),response,sizeof(struct _sdioresponse));
if(reply && !(rlen>16)) memcpy(reply,response,rlen);
// printf(" cmd= %08x\n", cmd);
return ret;
}
static s32 __sdio_setclock(u32 set)
{
s32 ret;
STACK_ALIGN(u32,clock,1,32);
*clock = set;
ret = IOS_Ioctl(__sd0_fd,IOCTL_SDIO_SETCLK,clock,sizeof(u32),NULL,0);
return ret;
}
static s32 __sdio_getstatus()
{
s32 ret;
STACK_ALIGN(u32,status,1,32);
ret = IOS_Ioctl(__sd0_fd,IOCTL_SDIO_GETSTATUS,NULL,0,status,sizeof(u32));
if(ret<0) return ret;
return *status;
}
static s32 __sdio_resetcard()
{
s32 ret;
STACK_ALIGN(u32,status,1,32);
__sd0_rca = 0;
ret = IOS_Ioctl(__sd0_fd,IOCTL_SDIO_RESETCARD,NULL,0,status,sizeof(u32));
if(ret<0) return ret;
__sd0_rca = (u16)(*status>>16);
return (*status&0xffff);
}
static s32 __sdio_gethcr(u8 reg, u8 size, u32 *val)
{
s32 ret;
STACK_ALIGN(u32,hcr_value,1,32);
STACK_ALIGN(u32,hcr_query,6,32);
if(val==NULL) return IPC_EINVAL;
*hcr_value = 0;
*val = 0;
hcr_query[0] = reg;
hcr_query[1] = 0;
hcr_query[2] = 0;
hcr_query[3] = size;
hcr_query[4] = 0;
hcr_query[5] = 0;
ret = IOS_Ioctl(__sd0_fd,IOCTL_SDIO_READHCREG,(void*)hcr_query,24,hcr_value,sizeof(u32));
*val = *hcr_value;
return ret;
}
static s32 __sdio_sethcr(u8 reg, u8 size, u32 data)
{
s32 ret;
STACK_ALIGN(u32,hcr_query,6,32);
hcr_query[0] = reg;
hcr_query[1] = 0;
hcr_query[2] = 0;
hcr_query[3] = size;
hcr_query[4] = data;
hcr_query[5] = 0;
ret = IOS_Ioctl(__sd0_fd,IOCTL_SDIO_WRITEHCREG,(void*)hcr_query,24,NULL,0);
return ret;
}
static s32 __sdio_waithcr(u8 reg, u8 size, u8 unset, u32 mask)
{
u32 val;
s32 ret;
s32 tries = 10;
while(tries-- > 0)
{
ret = __sdio_gethcr(reg, size, &val);
if(ret < 0) return ret;
if((unset && !(val & mask)) || (!unset && (val & mask))) return 0;
usleep(10000);
}
return -1;
}
static s32 __sdio_setbuswidth(u32 bus_width)
{
s32 ret;
u32 hc_reg = 0;
ret = __sdio_gethcr(SDIOHCR_HOSTCONTROL, 1, &hc_reg);
if(ret<0) return ret;
hc_reg &= 0xff;
hc_reg &= ~SDIOHCR_HOSTCONTROL_4BIT;
if(bus_width==4) hc_reg |= SDIOHCR_HOSTCONTROL_4BIT;
return __sdio_sethcr(SDIOHCR_HOSTCONTROL, 1, hc_reg);
}
static s32 __sd0_getrca()
{
s32 ret;
u32 rca;
ret = __sdio_sendcommand(SDIO_CMD_SENDRCA,0,SDIO_RESPONSE_R5,0,0,0,NULL,&rca,sizeof(rca));
if(ret<0) return ret;
__sd0_rca = (u16)(rca>>16);
return (rca&0xffff);
}
static s32 __sd0_select()
{
s32 ret;
ret = __sdio_sendcommand(SDIO_CMD_SELECT,SDIOCMD_TYPE_AC,SDIO_RESPONSE_R1B,(__sd0_rca<<16),0,0,NULL,NULL,0);
return ret;
}
static s32 __sd0_deselect()
{
s32 ret;
ret = __sdio_sendcommand(SDIO_CMD_DESELECT,SDIOCMD_TYPE_AC,SDIO_RESPONSE_R1B,0,0,0,NULL,NULL,0);
return ret;
}
static s32 __sd0_setblocklength(u32 blk_len)
{
s32 ret;
ret = __sdio_sendcommand(SDIO_CMD_SETBLOCKLEN,SDIOCMD_TYPE_AC,SDIO_RESPONSE_R1,blk_len,0,0,NULL,NULL,0);
return ret;
}
static s32 __sd0_setbuswidth(u32 bus_width)
{
u16 val;
s32 ret;
val = 0x0000;
if(bus_width==4) val = 0x0002;
ret = __sdio_sendcommand(SDIO_CMD_APPCMD,SDIOCMD_TYPE_AC,SDIO_RESPONSE_R1,(__sd0_rca<<16),0,0,NULL,NULL,0);
if(ret<0) return ret;
ret = __sdio_sendcommand(SDIO_ACMD_SETBUSWIDTH,SDIOCMD_TYPE_AC,SDIO_RESPONSE_R1,val,0,0,NULL,NULL,0);
return ret;
}
static s32 __sd0_getcid()
{
s32 ret;
ret = __sdio_sendcommand(SDIO_CMD_ALL_SENDCID,0,SDIO_RESPOSNE_R2,(__sd0_rca<<16),0,0,NULL,__sd0_cid,16);
return ret;
}
static bool __sd0_initio()
{
s32 ret;
s32 tries;
u32 status;
struct _sdioresponse resp;
__sdio_resetcard();
status = __sdio_getstatus();
if(!(status & SDIO_STATUS_CARD_INSERTED))
return false;
if(!(status & SDIO_STATUS_CARD_INITIALIZED))
{
// IOS doesn't like this card, so we need to convice it to accept it.
// reopen the handle which makes IOS clean stuff up
IOS_Close(__sd0_fd);
__sd0_fd = IOS_Open(_sd0_fs,1);
// reset the host controller
if(__sdio_sethcr(SDIOHCR_SOFTWARERESET, 1, 7) < 0) goto fail;
if(__sdio_waithcr(SDIOHCR_SOFTWARERESET, 1, 1, 7) < 0) goto fail;
// initialize interrupts (sd_reset_card does this on success)
__sdio_sethcr(0x34, 4, 0x13f00c3);
__sdio_sethcr(0x38, 4, 0x13f00c3);
// enable power
__sd0_sdhc = 1;
ret = __sdio_sethcr(SDIOHCR_POWERCONTROL, 1, 0xe);
if(ret < 0) goto fail;
ret = __sdio_sethcr(SDIOHCR_POWERCONTROL, 1, 0xf);
if(ret < 0) goto fail;
// enable internal clock, wait until it gets stable and enable sd clock
ret = __sdio_sethcr(SDIOHCR_CLOCKCONTROL, 2, 0);
if(ret < 0) goto fail;
ret = __sdio_sethcr(SDIOHCR_CLOCKCONTROL, 2, 0x101);
if(ret < 0) goto fail;
ret = __sdio_waithcr(SDIOHCR_CLOCKCONTROL, 2, 0, 2);
if(ret < 0) goto fail;
ret = __sdio_sethcr(SDIOHCR_CLOCKCONTROL, 2, 0x107);
if(ret < 0) goto fail;
// setup timeout
ret = __sdio_sethcr(SDIOHCR_TIMEOUTCONTROL, 1, SDIO_DEFAULT_TIMEOUT);
if(ret < 0) goto fail;
// standard SDHC initialization process
ret = __sdio_sendcommand(SDIO_CMD_GOIDLE, 0, 0, 0, 0, 0, NULL, NULL, 0);
if(ret < 0) goto fail;
ret = __sdio_sendcommand(SDIO_CMD_SENDIFCOND, 0, SDIO_RESPONSE_R6, 0x1aa, 0, 0, NULL, &resp, sizeof(resp));
if(ret < 0) goto fail;
if((resp.rsp_fields[0] & 0xff) != 0xaa) goto fail;
tries = 10;
while(tries-- > 0)
{
ret = __sdio_sendcommand(SDIO_CMD_APPCMD, SDIOCMD_TYPE_AC,SDIO_RESPONSE_R1,0,0,0,NULL,NULL,0);
if(ret < 0) goto fail;
ret = __sdio_sendcommand(SDIO_ACMD_SENDOPCOND, 0, SDIO_RESPONSE_R3, 0x40300000, 0, 0, NULL, &resp, sizeof(resp));
if(ret < 0) goto fail;
if(resp.rsp_fields[0] & (1 << 31)) break;
usleep(10000);
}
if(tries < 0) goto fail;
// FIXME: SDv2 cards which are not high-capacity won't work :/
if(resp.rsp_fields[0] & (1 << 30))
__sd0_sdhc = 1;
else
__sd0_sdhc = 0;
ret = __sd0_getcid();
if(ret < 0) goto fail;
ret = __sd0_getrca();
if(ret < 0) goto fail;
}
else if(status&SDIO_STATUS_CARD_SDHC)
__sd0_sdhc = 1;
else
__sd0_sdhc = 0;
ret = __sdio_setbuswidth(4);
if(ret<0) return false;
ret = __sdio_setclock(1);
if(ret<0) return false;
ret = __sd0_select();
if(ret<0) return false;
ret = __sd0_setblocklength(PAGE_SIZE512);
if(ret<0) {
ret = __sd0_deselect();
return false;
}
ret = __sd0_setbuswidth(4);
if(ret<0) {
ret = __sd0_deselect();
return false;
}
__sd0_deselect();
__sd0_initialized = 1;
return true;
fail:
__sdio_sethcr(SDIOHCR_SOFTWARERESET, 1, 7);
__sdio_waithcr(SDIOHCR_SOFTWARERESET, 1, 1, 7);
IOS_Close(__sd0_fd);
__sd0_fd = IOS_Open(_sd0_fs,1);
return false;
}
bool sdio_OGC_Deinitialize()
{
if(__sd0_fd>=0)
IOS_Close(__sd0_fd);
if(rw_buffer != NULL)
MEM2_lo_free(rw_buffer);
rw_buffer = NULL;
__sd0_fd = -1;
__sdio_initialized = 0;
return true;
}
bool sdio_OGC_Startup()
{
if(__sdio_initialized==1) return true;
if(rw_buffer == NULL) rw_buffer = MEM2_lo_alloc(4*1024);
if(rw_buffer == NULL) return false;
__sd0_fd = IOS_Open(_sd0_fs,1);
if(__sd0_fd<0) {
sdio_OGC_Deinitialize();
return false;
}
if(__sd0_initio()==false) {
sdio_OGC_Deinitialize();
return false;
}
__sdio_initialized = 1;
return true;
}
bool sdio_OGC_Shutdown()
{
if(__sd0_initialized==0) return false;
sdio_OGC_Deinitialize();
__sd0_initialized = 0;
return true;
}
bool sdio_OGC_ReadSectors(sec_t sector, sec_t numSectors,void* buffer)
{
s32 ret;
u8 *ptr;
sec_t blk_off;
if(buffer==NULL) return false;
ret = __sd0_select();
if(ret<0) return false;
if((u32)buffer & 0x1F) {
ptr = (u8*)buffer;
int secs_to_read;
while(numSectors>0) {
if(__sd0_sdhc == 0) blk_off = (sector*PAGE_SIZE512);
else blk_off = sector;
if(numSectors > 8)secs_to_read = 8;
else secs_to_read = numSectors;
ret = __sdio_sendcommand(SDIO_CMD_READMULTIBLOCK,SDIOCMD_TYPE_AC,SDIO_RESPONSE_R1,blk_off,secs_to_read,PAGE_SIZE512,rw_buffer,NULL,0);
if(ret>=0) {
memcpy(ptr,rw_buffer,PAGE_SIZE512*secs_to_read);
ptr += PAGE_SIZE512*secs_to_read;
sector+=secs_to_read;
numSectors-=secs_to_read;
} else
break;
}
} else {
if(__sd0_sdhc == 0) sector *= PAGE_SIZE512;
ret = __sdio_sendcommand(SDIO_CMD_READMULTIBLOCK,SDIOCMD_TYPE_AC,SDIO_RESPONSE_R1,sector,numSectors,PAGE_SIZE512,buffer,NULL,0);
}
__sd0_deselect();
return (ret>=0);
}
bool sdio_OGC_WriteSectors(sec_t sector, sec_t numSectors,const void* buffer)
{
s32 ret;
u8 *ptr;
u32 blk_off;
if(buffer==NULL) return false;
ret = __sd0_select();
if(ret<0) return false;
if((u32)buffer & 0x1F) {
ptr = (u8*)buffer;
int secs_to_write;
while(numSectors>0) {
if(__sd0_sdhc == 0) blk_off = (sector*PAGE_SIZE512);
else blk_off = sector;
if(numSectors > 8)secs_to_write = 8;
else secs_to_write = numSectors;
memcpy(rw_buffer,ptr,PAGE_SIZE512*secs_to_write);
ret = __sdio_sendcommand(SDIO_CMD_WRITEMULTIBLOCK,SDIOCMD_TYPE_AC,SDIO_RESPONSE_R1,blk_off,secs_to_write,PAGE_SIZE512,rw_buffer,NULL,0);
if(ret>=0) {
ptr += PAGE_SIZE512*secs_to_write;
sector+=secs_to_write;
numSectors-=secs_to_write;
} else
break;
}
} else {
if(__sd0_sdhc == 0) sector *= PAGE_SIZE512;
ret = __sdio_sendcommand(SDIO_CMD_WRITEMULTIBLOCK,SDIOCMD_TYPE_AC,SDIO_RESPONSE_R1,sector,numSectors,PAGE_SIZE512,(char *)buffer,NULL,0);
}
__sd0_deselect();
return (ret>=0);
}
bool sdio_OGC_ClearStatus()
{
return true;
}
bool sdio_OGC_IsInserted()
{
return ((__sdio_getstatus() & SDIO_STATUS_CARD_INSERTED) ==
SDIO_STATUS_CARD_INSERTED);
}
const DISC_INTERFACE __io_wiisd_ogc = {
DEVICE_TYPE_WII_SD,
FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_SD,
(FN_MEDIUM_STARTUP)&sdio_OGC_Startup,
(FN_MEDIUM_ISINSERTED)&sdio_OGC_IsInserted,
(FN_MEDIUM_READSECTORS)&sdio_OGC_ReadSectors,
(FN_MEDIUM_WRITESECTORS)&sdio_OGC_WriteSectors,
(FN_MEDIUM_CLEARSTATUS)&sdio_OGC_ClearStatus,
(FN_MEDIUM_SHUTDOWN)&sdio_OGC_Shutdown
};
#endif

View File

@ -0,0 +1,44 @@
/*
wii_sd.h
Hardware interface for libfat Wii internal SD
Copyright (c) 2008
Michael Wiedenbauer (shagkur)
Dave Murphy (WinterMute)
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __WIISD_LIBOGC_H__
#define __WIISD_LIBOGC_H__
#include <gctypes.h>
#include <ogc/disc_io.h>
#define DEVICE_TYPE_WII_SD (('W'<<24)|('I'<<16)|('S'<<8)|'D')
extern const DISC_INTERFACE __io_wiisd_ogc;
#endif