From c89190dc342105c56587c4ef0d9f1561bd4566fc Mon Sep 17 00:00:00 2001 From: dhewg Date: Sun, 17 May 2009 13:16:15 +0200 Subject: [PATCH] Possible fix for SDHC cards under IOS >= 6x. Thanks to svpe. --- libogc/wiisd.c | 186 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 92 insertions(+), 94 deletions(-) diff --git a/libogc/wiisd.c b/libogc/wiisd.c index 526451d..ec6ab80 100644 --- a/libogc/wiisd.c +++ b/libogc/wiisd.c @@ -47,20 +47,20 @@ #include #define SDIO_HEAPSIZE 0x400 - + #define PAGE_SIZE512 512 -#define SDIOHCR_RESPONSE 0x10 +#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_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 SDIO_DEFAULT_TIMEOUT 0xe + #define IOCTL_SDIO_WRITEHCREG 0x01 #define IOCTL_SDIO_READHCREG 0x02 #define IOCTL_SDIO_READCREG 0x03 @@ -75,12 +75,12 @@ #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 @@ -89,13 +89,13 @@ #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_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_SENDIFCOND 0x08 #define SDIO_CMD_SENDCSD 0x09 #define SDIO_CMD_SENDCID 0x0A #define SDIO_CMD_SENDSTATUS 0x0D @@ -105,17 +105,18 @@ #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_ACMD_SENDOPCOND 0x29 + +#define SDIO_STATUS_CARD_INSERTED 0x1 +#define SDIO_STATUS_CARD_INITIALIZED 0x10000 +#define SDIO_STATUS_CARD_SDHC 0x100000 -#define SDIO_STATUS_CARD_INSERTED 0x1 -#define SDIO_STATUS_CARD_INITIALIZED 0x10000 - #define READ_BL_LEN ((u8)(__sd0_csd[5]&0x0f)) #define WRITE_BL_LEN ((u8)(((__sd0_csd[12]&0x03)<<2)|((__sd0_csd[13]>>6)&0x03))) - + struct _sdiorequest { u32 cmd; @@ -128,24 +129,24 @@ struct _sdiorequest u32 isdma; u32 pad0; }; - + struct _sdioresponse { u32 rsp_fields[3]; u32 acmd12_response; }; - + static s32 hId = -1; - + 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) @@ -164,7 +165,7 @@ static s32 __sdio_sendcommand(u32 cmd,u32 cmd_type,u32 rsp_type,u32 arg,u32 blk_ 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); @@ -175,57 +176,57 @@ static s32 __sdio_sendcommand(u32 cmd,u32 cmd_type,u32 rsp_type,u32 arg,u32 blk_ 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); + 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); + 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; + + *hcr_value = 0; *val = 0; hcr_query[0] = reg; hcr_query[1] = 0; @@ -236,15 +237,14 @@ static s32 __sdio_gethcr(u8 reg, u8 size, u32 *val) 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; @@ -253,7 +253,6 @@ static s32 __sdio_sethcr(u8 reg, u8 size, u32 data) hcr_query[5] = 0; ret = IOS_Ioctl(__sd0_fd,IOCTL_SDIO_WRITEHCREG,(void*)hcr_query,24,NULL,0); - return ret; } @@ -273,107 +272,106 @@ static s32 __sdio_waithcr(u8 reg, u8 size, u8 unset, u32 mask) 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_getstatus() { s32 ret; u32 status = 0; - + ret = __sdio_sendcommand(SDIO_CMD_SENDSTATUS,SDIOCMD_TYPE_AC,SDIO_RESPONSE_R1,(__sd0_rca<<16),0,0,NULL,&status,sizeof(u32)); if(ret<0) return ret; - + return status; } - + 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_getcsd() { s32 ret; - + ret = __sdio_sendcommand(SDIO_CMD_SENDCSD,SDIOCMD_TYPE_AC,SDIO_RESPOSNE_R2,(__sd0_rca<<16),0,0,NULL,__sd0_csd,16); 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; @@ -455,24 +453,26 @@ static bool __sd0_initio() 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(); @@ -495,7 +495,7 @@ bool sdio_Deinitialize() { if(__sd0_fd>=0) IOS_Close(__sd0_fd); - + __sdio_initialized = 0; return true; } @@ -503,19 +503,19 @@ bool sdio_Deinitialize() bool sdio_Startup() { if(__sdio_initialized==1) return true; - + if(hId<0) { hId = iosCreateHeap(SDIO_HEAPSIZE); if(hId<0) return false; } - + __sd0_fd = IOS_Open(_sd0_fs,1); if(__sd0_fd<0) { sdio_Deinitialize(); return false; } - + if(__sd0_initio()==false) { sdio_Deinitialize(); return false; @@ -523,27 +523,25 @@ bool sdio_Startup() __sdio_initialized = 1; return true; } - - - + bool sdio_Shutdown() { if(__sd0_initialized==0) return false; sdio_Deinitialize(); - + __sd0_initialized = 0; return true; } - + bool sdio_ReadSectors(sec_t sector, sec_t numSectors,void* buffer) { s32 ret; u8 *rbuf,*ptr; sec_t blk_off; - + if(buffer==NULL) return false; - + ret = __sd0_select(); if(ret<0) return false; @@ -575,18 +573,18 @@ bool sdio_ReadSectors(sec_t sector, sec_t numSectors,void* buffer) } __sd0_deselect(); - + return (ret>=0); } - + bool sdio_WriteSectors(sec_t sector, sec_t numSectors,const void* buffer) { s32 ret; u8 *wbuf,*ptr; u32 blk_off; - + if(buffer==NULL) return false; - + ret = __sd0_select(); if(ret<0) return false; @@ -617,15 +615,15 @@ bool sdio_WriteSectors(sec_t sector, sec_t numSectors,const void* buffer) } __sd0_deselect(); - + return (ret>=0); } - + bool sdio_ClearStatus() { return true; } - + bool sdio_IsInserted() { return ((__sdio_getstatus() & SDIO_STATUS_CARD_INSERTED) == -- 2.11.4.GIT