@@ -147,11 +147,10 @@ static u16 __sd0_rca = 0;
147147static s32 __sd0_sdhc = 0 ;
148148static u8 __sd0_csd [16 ];
149149static u8 __sd0_cid [16 ];
150- static u8 __sd0_functions [64 ] ATTRIBUTE_ALIGN (32 );
151150static bool __sdio_initialized = false;
152151static 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+
189196static 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