mirror of
https://github.com/Fledge68/WiiFlow_Lite.git
synced 2024-11-01 00:55:06 +01:00
-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:
parent
8fbd49ab7d
commit
b700d056b8
@ -27,11 +27,11 @@
|
||||
#include <ogc/mutex.h>
|
||||
#include <ogc/system.h>
|
||||
#include <sdcard/gcsd.h>
|
||||
#include <sdcard/wiisd_io.h>
|
||||
#include "DeviceHandler.hpp"
|
||||
#include "fat.h"
|
||||
#include "sdhc.h"
|
||||
#include "usbthread.h"
|
||||
#include "sdhc.h"
|
||||
#include "wiisd_libogc.h"
|
||||
#include "usbstorage.h"
|
||||
#include "usbstorage_libogc.h"
|
||||
#include "loader/cios.h"
|
||||
@ -332,7 +332,7 @@ void DeviceHandler::WaitForDevice(const DISC_INTERFACE *Handle)
|
||||
bool DeviceHandler::MountDevolution()
|
||||
{
|
||||
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 */
|
||||
WaitForDevice(handle);
|
||||
/* Only mount the partition we need */
|
||||
|
@ -2,9 +2,9 @@
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <ogcsys.h>
|
||||
#include <sdcard/wiisd_io.h>
|
||||
#include "memory/mem2.hpp"
|
||||
#include "sdhc.h"
|
||||
#include "wiisd_libogc.h"
|
||||
#include "memory/mem2.hpp"
|
||||
|
||||
/* IOCTL comamnds */
|
||||
#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 u32 sector_size = SDHC_SECTOR_SIZE;
|
||||
static void *sdhc_buf2;
|
||||
static void *sdhc_buf2 = NULL;
|
||||
|
||||
bool SDHC_Init(void)
|
||||
{
|
||||
@ -33,7 +33,7 @@ bool SDHC_Init(void)
|
||||
|
||||
if (sdhc_mode_sd)
|
||||
{
|
||||
sdhc_inited = __io_wiisd.startup();
|
||||
sdhc_inited = __io_wiisd_ogc.startup();
|
||||
return sdhc_inited;
|
||||
}
|
||||
|
||||
@ -45,11 +45,9 @@ bool SDHC_Init(void)
|
||||
if (hid < 0) goto err;
|
||||
|
||||
// allocate buf2
|
||||
if (sdhc_buf2 == NULL)
|
||||
{
|
||||
if(sdhc_buf2 == NULL)
|
||||
sdhc_buf2 = MEM2_lo_alloc(SDHC_MEM2_SIZE);
|
||||
if (sdhc_buf2 == NULL) goto err;
|
||||
}
|
||||
if(sdhc_buf2 == NULL) goto err;
|
||||
|
||||
/* Open SDHC device */
|
||||
fd = IOS_Open(fs, 0);
|
||||
@ -76,15 +74,17 @@ err:
|
||||
bool SDHC_Close(void)
|
||||
{
|
||||
sdhc_inited = 0;
|
||||
if (sdhc_mode_sd) {
|
||||
return __io_wiisd.shutdown();
|
||||
}
|
||||
if(sdhc_mode_sd)
|
||||
return __io_wiisd_ogc.shutdown();
|
||||
|
||||
/* Close SDHC device */
|
||||
if (fd >= 0) {
|
||||
if(fd >= 0) {
|
||||
IOS_Close(fd);
|
||||
fd = -1;
|
||||
}
|
||||
if(sdhc_buf2 != NULL)
|
||||
MEM2_lo_free(sdhc_buf2);
|
||||
sdhc_buf2 = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -92,9 +92,8 @@ bool SDHC_Close(void)
|
||||
bool SDHC_IsInserted(void)
|
||||
{
|
||||
s32 ret;
|
||||
if (sdhc_mode_sd) {
|
||||
return __io_wiisd.isInserted();
|
||||
}
|
||||
if(sdhc_mode_sd)
|
||||
return __io_wiisd_ogc.isInserted();
|
||||
|
||||
/* Check if SD card is inserted */
|
||||
ret = IOS_IoctlvFormat(hid, fd, IOCTL_SDHC_ISINSERTED, ":");
|
||||
@ -104,8 +103,8 @@ bool SDHC_IsInserted(void)
|
||||
|
||||
bool SDHC_ReadSectors(u32 sector, u32 count, void *buffer)
|
||||
{
|
||||
if (sdhc_mode_sd)
|
||||
return __io_wiisd.readSectors(sector, count, buffer);
|
||||
if(sdhc_mode_sd)
|
||||
return __io_wiisd_ogc.readSectors(sector, count, buffer);
|
||||
|
||||
u32 size;
|
||||
s32 ret = -1;
|
||||
@ -155,8 +154,8 @@ bool SDHC_ReadSectors(u32 sector, u32 count, void *buffer)
|
||||
|
||||
bool SDHC_WriteSectors(u32 sector, u32 count, void *buffer)
|
||||
{
|
||||
if (sdhc_mode_sd)
|
||||
return __io_wiisd.writeSectors(sector, count, buffer);
|
||||
if(sdhc_mode_sd)
|
||||
return __io_wiisd_ogc.writeSectors(sector, count, buffer);
|
||||
|
||||
u32 size;
|
||||
s32 ret = -1;
|
||||
|
@ -128,6 +128,9 @@ void USBStorage2_Deinit()
|
||||
}
|
||||
else if(fd >= 0)
|
||||
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 */
|
||||
if(usb2_port == 0 || usb2_port == 1)
|
||||
|
@ -207,9 +207,11 @@ s32 USBStorage_OGC_Initialize()
|
||||
|
||||
_CPU_ISR_Disable(level);
|
||||
LWP_InitQueue(&__usbstorage_ogc_waitq);
|
||||
if(!arena_ptr) {
|
||||
if(arena_ptr == NULL)
|
||||
arena_ptr = (u8*)MEM2_lo_alloc(HEAP_SIZE);
|
||||
}
|
||||
if(arena_ptr == NULL)
|
||||
return IPC_ENOMEM;
|
||||
|
||||
__lwp_heap_init(&__heap, arena_ptr, HEAP_SIZE, 32);
|
||||
cbw_buffer=(u8*)__lwp_heap_allocate(&__heap, 32);
|
||||
__inited = true;
|
||||
@ -949,6 +951,9 @@ static bool __usbstorage_ogc_Shutdown(void)
|
||||
{
|
||||
if (__vid != 0 || __pid != 0)
|
||||
USBStorage_OGC_Close(&__usbfd);
|
||||
if(arena_ptr != NULL)
|
||||
MEM2_lo_free(arena_ptr);
|
||||
arena_ptr = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
615
source/devicemounter/wiisd_libogc.c
Normal file
615
source/devicemounter/wiisd_libogc.c
Normal 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
|
44
source/devicemounter/wiisd_libogc.h
Normal file
44
source/devicemounter/wiisd_libogc.h
Normal 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
|
Loading…
Reference in New Issue
Block a user