Skip to content

Commit ff53c4a

Browse files
DacoTacofincs
authored andcommitted
WiiSD: never split a buffer across 4k boundary #276
1 parent adf4c78 commit ff53c4a

1 file changed

Lines changed: 15 additions & 7 deletions

File tree

‎libogc/wiisd.c‎

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,10 @@ static u16 __sd0_rca = 0;
147147
static s32 __sd0_sdhc = 0;
148148
static u8 __sd0_csd[16];
149149
static u8 __sd0_cid[16];
150-
static u8 __sd0_functions[64] ATTRIBUTE_ALIGN(32);
151150
static bool __sdio_initialized = false;
152151
static char _sd0_fs[] ATTRIBUTE_ALIGN(32) = "/dev/sdio/slot0";
153152

154-
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)
153+
static s32 __sdio_sendcommandimpl(u32 cmd,u32 cmd_type,u32 rsp_type,u32 arg,u32 blk_cnt,u32 blk_size,void *buffer,void *reply,u32 rlen)
155154
{
156155
s32 ret;
157156
STACK_ALIGN(ioctlv,iovec,3,32);
@@ -185,7 +184,15 @@ static s32 __sdio_sendcommand(u32 cmd,u32 cmd_type,u32 rsp_type,u32 arg,u32 blk_
185184

186185
return ret;
187186
}
188-
187+
//There is an IOS bug where it doesn't enable the DMA interrupt on cmd_type SDIOCMD_TYPE_BC
188+
//this makes it so if a buffer crosses a 4k boundary it will hang
189+
#define __sdio_sendcommand(cmd, cmd_type, rsp_type,arg, blk_cnt, blk_size, buffer, reply, rlen) \
190+
({ \
191+
_Static_assert((cmd_type) != SDIOCMD_TYPE_BC || ((blk_cnt)*(blk_size) <= 0x1000 && (blk_cnt)*(blk_size) <= __alignof__(buffer)), \
192+
"SDIOCMD_TYPE_BC transfer may cross a 4K boundary: align the buffer"); \
193+
__sdio_sendcommandimpl(cmd, cmd_type, rsp_type,arg, blk_cnt, blk_size, buffer, reply, rlen); \
194+
})
195+
189196
static s32 __sdio_setclock(u32 set)
190197
{
191198
s32 ret;
@@ -387,6 +394,7 @@ static bool __sd0_initio(void)
387394
u32 status;
388395
u32 clock = 1;
389396
struct _sdioresponse resp;
397+
u8 sd0_functions[64] ATTRIBUTE_ALIGN(64);
390398

391399
__sdio_resetcard();
392400
status = __sdio_getstatus();
@@ -486,20 +494,20 @@ static bool __sd0_initio(void)
486494
}
487495

488496
if(CCC & (1 << 10)) {
489-
ret = __sdio_sendcommand(SDIO_CMD_SWITCHFUNC, 1, SDIO_RESPONSE_R1, 0x00fffff0, 1, sizeof(__sd0_functions), __sd0_functions, NULL, 0);
497+
ret = __sdio_sendcommand(SDIO_CMD_SWITCHFUNC, SDIOCMD_TYPE_BC, SDIO_RESPONSE_R1, 0x00fffff0, 1, sizeof(sd0_functions), sd0_functions, NULL, 0);
490498
if(ret<0) {
491499
__sd0_deselect();
492500
return false;
493501
}
494502

495-
if(((u16*)__sd0_functions)[6] & (1 << 1)) {
496-
ret = __sdio_sendcommand(SDIO_CMD_SWITCHFUNC, 1, SDIO_RESPONSE_R1, 0x80fffff1, 1, sizeof(__sd0_functions), __sd0_functions, NULL, 0);
503+
if(((u16*)sd0_functions)[6] & (1 << 1)) {
504+
ret = __sdio_sendcommand(SDIO_CMD_SWITCHFUNC, SDIOCMD_TYPE_BC, SDIO_RESPONSE_R1, 0x80fffff1, 1, sizeof(sd0_functions), sd0_functions, NULL, 0);
497505
if(ret<0) {
498506
__sd0_deselect();
499507
return false;
500508
}
501509

502-
if((__sd0_functions[16] & 0xf) == 1) {
510+
if((sd0_functions[16] & 0xf) == 1) {
503511
ret = __sdio_setbuswidth(true, SDIOHCR_HOSTCONTROL_HS);
504512
if(ret<0) {
505513
__sd0_deselect();

0 commit comments

Comments
 (0)