فهرست منبع

Fix race condition in GD32 SDIO driver

This caused read errors with error code 8 and 19 randomly, especially if DMA enabled.
The GD32 driver code never disabled the command state machine and
issued multiple writes to the CMDCTL register. This caused the
same command to be executed multiple times if interrupt occurred
in between the register modifications.
Petteri Aimonen 3 سال پیش
والد
کامیت
9744b21b17
1فایلهای تغییر یافته به همراه44 افزوده شده و 0 حذف شده
  1. 44 0
      lib/AzulSCSI_platform_GD32F205/gd32_sdio_sdcard.c

+ 44 - 0
lib/AzulSCSI_platform_GD32F205/gd32_sdio_sdcard.c

@@ -204,6 +204,7 @@ sd_error_enum sd_card_init(void)
     /* the card is not I/O only card */
     if(SDIO_SECURE_DIGITAL_IO_CARD != cardtype) {
         /* send CMD2(SD_CMD_ALL_SEND_CID) to get the CID numbers */
+        sdio_csm_disable();
         sdio_command_response_config(SD_CMD_ALL_SEND_CID, (uint32_t)0x0, SDIO_RESPONSETYPE_LONG);
         sdio_wait_type_set(SDIO_WAITTYPE_NO);
         sdio_csm_enable();
@@ -224,6 +225,7 @@ sd_error_enum sd_card_init(void)
     if((SDIO_STD_CAPACITY_SD_CARD_V1_1 == cardtype) || (SDIO_STD_CAPACITY_SD_CARD_V2_0 == cardtype) ||
             (SDIO_HIGH_CAPACITY_SD_CARD == cardtype) || (SDIO_SECURE_DIGITAL_IO_COMBO_CARD == cardtype)) {
         /* send CMD3(SEND_RELATIVE_ADDR) to ask the card to publish a new relative address (RCA) */
+        sdio_csm_disable();
         sdio_command_response_config(SD_CMD_SEND_RELATIVE_ADDR, (uint32_t)0x0, SDIO_RESPONSETYPE_SHORT);
         sdio_wait_type_set(SDIO_WAITTYPE_NO);
         sdio_csm_enable();
@@ -239,6 +241,7 @@ sd_error_enum sd_card_init(void)
         sd_rca = temp_rca;
 
         /* send CMD9(SEND_CSD) to get the addressed card's card-specific data (CSD) */
+        sdio_csm_disable();
         sdio_command_response_config(SD_CMD_SEND_CSD, (uint32_t)(temp_rca << SD_RCA_SHIFT), SDIO_RESPONSETYPE_LONG);
         sdio_wait_type_set(SDIO_WAITTYPE_NO);
         sdio_csm_enable();
@@ -278,6 +281,7 @@ sd_error_enum sd_power_on(void)
     sdio_clock_enable();
 
     /* send CMD0(GO_IDLE_STATE) to reset the card */
+    sdio_csm_disable();
     sdio_command_response_config(SD_CMD_GO_IDLE_STATE, (uint32_t)0x0, SDIO_RESPONSETYPE_NO);
     sdio_wait_type_set(SDIO_WAITTYPE_NO);
     /* enable the CSM */
@@ -290,6 +294,7 @@ sd_error_enum sd_power_on(void)
     }
 
     /* send CMD8(SEND_IF_COND) to get SD memory card interface condition */
+    sdio_csm_disable();
     sdio_command_response_config(SD_CMD_SEND_IF_COND, SD_CHECK_PATTERN, SDIO_RESPONSETYPE_SHORT);
     sdio_wait_type_set(SDIO_WAITTYPE_NO);
     sdio_csm_enable();
@@ -301,6 +306,7 @@ sd_error_enum sd_power_on(void)
     }
 
     /* send CMD55(APP_CMD) to indicate next command is application specific command */
+    sdio_csm_disable();
     sdio_command_response_config(SD_CMD_APP_CMD, (uint32_t)0x0, SDIO_RESPONSETYPE_SHORT);
     sdio_wait_type_set(SDIO_WAITTYPE_NO);
     sdio_csm_enable();
@@ -309,6 +315,7 @@ sd_error_enum sd_power_on(void)
         /* SD memory card */
         while((!busyflag) && (count < SD_MAX_VOLT_VALIDATION)) {
             /* send CMD55(APP_CMD) to indicate next command is application specific command */
+            sdio_csm_disable();
             sdio_command_response_config(SD_CMD_APP_CMD, (uint32_t)0x0, SDIO_RESPONSETYPE_SHORT);
             sdio_wait_type_set(SDIO_WAITTYPE_NO);
             sdio_csm_enable();
@@ -319,6 +326,7 @@ sd_error_enum sd_power_on(void)
             }
 
             /* send ACMD41(SD_SEND_OP_COND) to get host capacity support information (HCS) and OCR content */
+            sdio_csm_disable();
             sdio_command_response_config(SD_APPCMD_SD_SEND_OP_COND, (SD_VOLTAGE_WINDOW | sdcardtype), SDIO_RESPONSETYPE_SHORT);
             sdio_wait_type_set(SDIO_WAITTYPE_NO);
             sdio_csm_enable();
@@ -467,6 +475,7 @@ sd_error_enum sd_block_read(uint32_t *preadbuffer, uint64_t readaddr, uint16_t b
     if((blocksize > 0) && (blocksize <= 2048) && (0 == align)) {
         datablksize = sd_datablocksize_get(blocksize);
         /* send CMD16(SET_BLOCKLEN) to set the block length */
+        sdio_csm_disable();
         sdio_command_response_config(SD_CMD_SET_BLOCKLEN, (uint32_t)blocksize, SDIO_RESPONSETYPE_SHORT);
         sdio_wait_type_set(SDIO_WAITTYPE_NO);
         sdio_csm_enable();
@@ -490,6 +499,7 @@ sd_error_enum sd_block_read(uint32_t *preadbuffer, uint64_t readaddr, uint16_t b
     sdio_dsm_enable();
 
     /* send CMD17(READ_SINGLE_BLOCK) to read a block */
+    sdio_csm_disable();
     sdio_command_response_config(SD_CMD_READ_SINGLE_BLOCK, (uint32_t)readaddr, SDIO_RESPONSETYPE_SHORT);
     sdio_wait_type_set(SDIO_WAITTYPE_NO);
     sdio_csm_enable();
@@ -602,6 +612,7 @@ sd_error_enum sd_multiblocks_read(uint32_t *preadbuffer, uint64_t readaddr, uint
     if((blocksize > 0) && (blocksize <= 2048) && (0 == align)) {
         datablksize = sd_datablocksize_get(blocksize);
         /* send CMD16(SET_BLOCKLEN) to set the block length */
+        sdio_csm_disable();
         sdio_command_response_config(SD_CMD_SET_BLOCKLEN, (uint32_t)blocksize, SDIO_RESPONSETYPE_SHORT);
         sdio_wait_type_set(SDIO_WAITTYPE_NO);
         sdio_csm_enable();
@@ -632,6 +643,7 @@ sd_error_enum sd_multiblocks_read(uint32_t *preadbuffer, uint64_t readaddr, uint
         sdio_dsm_enable();
 
         /* send CMD18(READ_MULTIPLE_BLOCK) to read multiple blocks */
+        sdio_csm_disable();
         sdio_command_response_config(SD_CMD_READ_MULTIPLE_BLOCK, readaddr, SDIO_RESPONSETYPE_SHORT);
         sdio_wait_type_set(SDIO_WAITTYPE_NO);
         sdio_csm_enable();
@@ -680,6 +692,7 @@ sd_error_enum sd_multiblocks_read(uint32_t *preadbuffer, uint64_t readaddr, uint
                 if((SDIO_STD_CAPACITY_SD_CARD_V1_1 == cardtype) || (SDIO_STD_CAPACITY_SD_CARD_V2_0 == cardtype) ||
                         (SDIO_HIGH_CAPACITY_SD_CARD == cardtype)) {
                     /* send CMD12(STOP_TRANSMISSION) to stop transmission */
+                    sdio_csm_disable();
                     sdio_command_response_config(SD_CMD_STOP_TRANSMISSION, (uint32_t)0x0, SDIO_RESPONSETYPE_SHORT);
                     sdio_wait_type_set(SDIO_WAITTYPE_NO);
                     sdio_csm_enable();
@@ -771,6 +784,7 @@ sd_error_enum sd_block_write(uint32_t *pwritebuffer, uint64_t writeaddr, uint16_
     if((blocksize > 0) && (blocksize <= 2048) && (0 == align)) {
         datablksize = sd_datablocksize_get(blocksize);
         /* send CMD16(SET_BLOCKLEN) to set the block length */
+        sdio_csm_disable();
         sdio_command_response_config(SD_CMD_SET_BLOCKLEN, (uint32_t)blocksize, SDIO_RESPONSETYPE_SHORT);
         sdio_wait_type_set(SDIO_WAITTYPE_NO);
         sdio_csm_enable();
@@ -786,6 +800,7 @@ sd_error_enum sd_block_write(uint32_t *pwritebuffer, uint64_t writeaddr, uint16_
     }
 
     /* send CMD13(SEND_STATUS), addressed card sends its status registers */
+    sdio_csm_disable();
     sdio_command_response_config(SD_CMD_SEND_STATUS, (uint32_t)sd_rca << SD_RCA_SHIFT, SDIO_RESPONSETYPE_SHORT);
     sdio_wait_type_set(SDIO_WAITTYPE_NO);
     sdio_csm_enable();
@@ -810,6 +825,7 @@ sd_error_enum sd_block_write(uint32_t *pwritebuffer, uint64_t writeaddr, uint16_
         }
 
         /* send CMD13(SEND_STATUS), addressed card sends its status registers */
+        sdio_csm_disable();
         sdio_command_response_config(SD_CMD_SEND_STATUS, (uint32_t)sd_rca << SD_RCA_SHIFT, SDIO_RESPONSETYPE_SHORT);
         sdio_wait_type_set(SDIO_WAITTYPE_NO);
         sdio_csm_enable();
@@ -822,6 +838,7 @@ sd_error_enum sd_block_write(uint32_t *pwritebuffer, uint64_t writeaddr, uint16_
     }
 
     /* send CMD24(WRITE_BLOCK) to write a block */
+    sdio_csm_disable();
     sdio_command_response_config(SD_CMD_WRITE_BLOCK, writeaddr, SDIO_RESPONSETYPE_SHORT);
     sdio_wait_type_set(SDIO_WAITTYPE_NO);
     sdio_csm_enable();
@@ -974,6 +991,7 @@ sd_error_enum sd_multiblocks_write(uint32_t *pwritebuffer, uint64_t writeaddr, u
     if((blocksize > 0) && (blocksize <= 2048) && (0 == align)) {
         datablksize = sd_datablocksize_get(blocksize);
         /* send CMD16(SET_BLOCKLEN) to set the block length */
+        sdio_csm_disable();
         sdio_command_response_config(SD_CMD_SET_BLOCKLEN, (uint32_t)blocksize, SDIO_RESPONSETYPE_SHORT);
         sdio_wait_type_set(SDIO_WAITTYPE_NO);
         sdio_csm_enable();
@@ -989,6 +1007,7 @@ sd_error_enum sd_multiblocks_write(uint32_t *pwritebuffer, uint64_t writeaddr, u
     }
 
     /* send CMD13(SEND_STATUS), addressed card sends its status registers */
+    sdio_csm_disable();
     sdio_command_response_config(SD_CMD_SEND_STATUS, (uint32_t)sd_rca << SD_RCA_SHIFT, SDIO_RESPONSETYPE_SHORT);
     sdio_wait_type_set(SDIO_WAITTYPE_NO);
     sdio_csm_enable();
@@ -1007,6 +1026,7 @@ sd_error_enum sd_multiblocks_write(uint32_t *pwritebuffer, uint64_t writeaddr, u
         if((SDIO_STD_CAPACITY_SD_CARD_V1_1 == cardtype) || (SDIO_STD_CAPACITY_SD_CARD_V2_0 == cardtype) ||
                 (SDIO_HIGH_CAPACITY_SD_CARD == cardtype)) {
             /* send CMD55(APP_CMD) to indicate next command is application specific command */
+            sdio_csm_disable();
             sdio_command_response_config(SD_CMD_APP_CMD, (uint32_t)sd_rca << SD_RCA_SHIFT, SDIO_RESPONSETYPE_SHORT);
             sdio_wait_type_set(SDIO_WAITTYPE_NO);
             sdio_csm_enable();
@@ -1017,6 +1037,7 @@ sd_error_enum sd_multiblocks_write(uint32_t *pwritebuffer, uint64_t writeaddr, u
             }
 
             /* send ACMD23(SET_WR_BLK_ERASE_COUNT) to set the number of write blocks to be preerased before writing */
+            sdio_csm_disable();
             sdio_command_response_config(SD_APPCMD_SET_WR_BLK_ERASE_COUNT, blocksnumber, SDIO_RESPONSETYPE_SHORT);
             sdio_wait_type_set(SDIO_WAITTYPE_NO);
             sdio_csm_enable();
@@ -1027,6 +1048,7 @@ sd_error_enum sd_multiblocks_write(uint32_t *pwritebuffer, uint64_t writeaddr, u
             }
         }
         /* send CMD25(WRITE_MULTIPLE_BLOCK) to continuously write blocks of data */
+        sdio_csm_disable();
         sdio_command_response_config(SD_CMD_WRITE_MULTIPLE_BLOCK, writeaddr, SDIO_RESPONSETYPE_SHORT);
         sdio_wait_type_set(SDIO_WAITTYPE_NO);
         sdio_csm_enable();
@@ -1090,6 +1112,7 @@ sd_error_enum sd_multiblocks_write(uint32_t *pwritebuffer, uint64_t writeaddr, u
                 if((SDIO_STD_CAPACITY_SD_CARD_V1_1 == cardtype) || (SDIO_STD_CAPACITY_SD_CARD_V2_0 == cardtype) ||
                         (SDIO_HIGH_CAPACITY_SD_CARD == cardtype)) {
                     /* send CMD12(STOP_TRANSMISSION) to stop transmission */
+                    sdio_csm_disable();
                     sdio_command_response_config(SD_CMD_STOP_TRANSMISSION, (uint32_t)0x0, SDIO_RESPONSETYPE_SHORT);
                     sdio_wait_type_set(SDIO_WAITTYPE_NO);
                     sdio_csm_enable();
@@ -1194,6 +1217,7 @@ sd_error_enum sd_erase(uint64_t startaddr, uint64_t endaddr)
     if((SDIO_STD_CAPACITY_SD_CARD_V1_1 == cardtype) || (SDIO_STD_CAPACITY_SD_CARD_V2_0 == cardtype) ||
             (SDIO_HIGH_CAPACITY_SD_CARD == cardtype)) {
         /* send CMD32(ERASE_WR_BLK_START) to set the address of the first write block to be erased */
+        sdio_csm_disable();
         sdio_command_response_config(SD_CMD_ERASE_WR_BLK_START, startaddr, SDIO_RESPONSETYPE_SHORT);
         sdio_wait_type_set(SDIO_WAITTYPE_NO);
         sdio_csm_enable();
@@ -1204,6 +1228,7 @@ sd_error_enum sd_erase(uint64_t startaddr, uint64_t endaddr)
         }
 
         /* send CMD33(ERASE_WR_BLK_END) to set the address of the last write block of the continuous range to be erased */
+        sdio_csm_disable();
         sdio_command_response_config(SD_CMD_ERASE_WR_BLK_END, endaddr, SDIO_RESPONSETYPE_SHORT);
         sdio_wait_type_set(SDIO_WAITTYPE_NO);
         sdio_csm_enable();
@@ -1215,6 +1240,7 @@ sd_error_enum sd_erase(uint64_t startaddr, uint64_t endaddr)
     }
 
     /* send CMD38(ERASE) to set the address of the first write block to be erased */
+    sdio_csm_disable();
     sdio_command_response_config(SD_CMD_ERASE, (uint32_t)0x0, SDIO_RESPONSETYPE_SHORT);
     sdio_wait_type_set(SDIO_WAITTYPE_NO);
     sdio_csm_enable();
@@ -1321,6 +1347,7 @@ sd_error_enum sd_card_select_deselect(uint16_t cardrca)
 {
     sd_error_enum status = SD_OK;
     /* send CMD7(SELECT/DESELECT_CARD) to select or deselect the card */
+    sdio_csm_disable();
     sdio_command_response_config(SD_CMD_SELECT_DESELECT_CARD, (uint32_t)(cardrca << SD_RCA_SHIFT), SDIO_RESPONSETYPE_SHORT);
     sdio_wait_type_set(SDIO_WAITTYPE_NO);
     sdio_csm_enable();
@@ -1344,6 +1371,7 @@ sd_error_enum sd_cardstatus_get(uint32_t *pcardstatus)
     }
 
     /* send CMD13(SEND_STATUS), addressed card sends its status register */
+    sdio_csm_disable();
     sdio_command_response_config(SD_CMD_SEND_STATUS, (uint32_t)sd_rca << SD_RCA_SHIFT, SDIO_RESPONSETYPE_SHORT);
     sdio_wait_type_set(SDIO_WAITTYPE_NO);
     sdio_csm_enable();
@@ -1375,6 +1403,7 @@ sd_error_enum sd_sdstatus_get(uint32_t *psdstatus)
     }
 
     /* send CMD16(SET_BLOCKLEN) to set the block length */
+    sdio_csm_disable();
     sdio_command_response_config(SD_CMD_SET_BLOCKLEN, (uint32_t)64, SDIO_RESPONSETYPE_SHORT);
     sdio_wait_type_set(SDIO_WAITTYPE_NO);
     sdio_csm_enable();
@@ -1385,6 +1414,7 @@ sd_error_enum sd_sdstatus_get(uint32_t *psdstatus)
     }
 
     /* send CMD55(APP_CMD) to indicate next command is application specific command */
+    sdio_csm_disable();
     sdio_command_response_config(SD_CMD_APP_CMD, (uint32_t)sd_rca << SD_RCA_SHIFT, SDIO_RESPONSETYPE_SHORT);
     sdio_wait_type_set(SDIO_WAITTYPE_NO);
     sdio_csm_enable();
@@ -1400,6 +1430,7 @@ sd_error_enum sd_sdstatus_get(uint32_t *psdstatus)
     sdio_dsm_enable();
 
     /* send ACMD13(SD_STATUS) to get the SD status */
+    sdio_csm_disable();
     sdio_command_response_config(SD_APPCMD_SD_STATUS, (uint32_t)0x0, SDIO_RESPONSETYPE_SHORT);
     sdio_wait_type_set(SDIO_WAITTYPE_NO);
     sdio_csm_enable();
@@ -1461,6 +1492,7 @@ sd_error_enum sd_transfer_stop(void)
 {
     sd_error_enum status = SD_OK;
     /* send CMD12(STOP_TRANSMISSION) to stop transmission */
+    sdio_csm_disable();
     sdio_command_response_config(SD_CMD_STOP_TRANSMISSION, (uint32_t)0x0, SDIO_RESPONSETYPE_SHORT);
     sdio_wait_type_set(SDIO_WAITTYPE_NO);
     sdio_csm_enable();
@@ -1507,6 +1539,7 @@ sd_error_enum sd_lock_unlock(uint8_t lockstate)
     sdio_dma_disable();
 
     /* send CMD16(SET_BLOCKLEN) to set the block length */
+    sdio_csm_disable();
     sdio_command_response_config(SD_CMD_SET_BLOCKLEN, (uint32_t)8, SDIO_RESPONSETYPE_SHORT);
     sdio_wait_type_set(SDIO_WAITTYPE_NO);
     sdio_csm_enable();
@@ -1517,6 +1550,7 @@ sd_error_enum sd_lock_unlock(uint8_t lockstate)
     }
 
     /* send CMD13(SEND_STATUS), addressed card sends its status register */
+    sdio_csm_disable();
     sdio_command_response_config(SD_CMD_SEND_STATUS, (uint32_t)sd_rca << SD_RCA_SHIFT, SDIO_RESPONSETYPE_SHORT);
     sdio_wait_type_set(SDIO_WAITTYPE_NO);
     sdio_csm_enable();
@@ -1532,6 +1566,7 @@ sd_error_enum sd_lock_unlock(uint8_t lockstate)
         /* continue to send CMD13 to polling the state of card until buffer empty or timeout */
         --timeout;
         /* send CMD13(SEND_STATUS), addressed card sends its status registers */
+        sdio_csm_disable();
         sdio_command_response_config(SD_CMD_SEND_STATUS, (uint32_t)sd_rca << SD_RCA_SHIFT, SDIO_RESPONSETYPE_SHORT);
         sdio_wait_type_set(SDIO_WAITTYPE_NO);
         sdio_csm_enable();
@@ -1547,6 +1582,7 @@ sd_error_enum sd_lock_unlock(uint8_t lockstate)
     }
 
     /* send CMD42(LOCK_UNLOCK) to set/reset the password or lock/unlock the card */
+    sdio_csm_disable();
     sdio_command_response_config(SD_CMD_LOCK_UNLOCK, (uint32_t)0x0, SDIO_RESPONSETYPE_SHORT);
     sdio_wait_type_set(SDIO_WAITTYPE_NO);
     sdio_csm_enable();
@@ -2166,6 +2202,7 @@ static sd_error_enum sd_card_state_get(uint8_t *pcardstate)
     __IO uint32_t reg_status = 0, response = 0;
 
     /* send CMD13(SEND_STATUS), addressed card sends its status register */
+    sdio_csm_disable();
     sdio_command_response_config(SD_CMD_SEND_STATUS, (uint32_t)sd_rca << SD_RCA_SHIFT, SDIO_RESPONSETYPE_SHORT);
     sdio_wait_type_set(SDIO_WAITTYPE_NO);
     sdio_csm_enable();
@@ -2234,6 +2271,7 @@ static sd_error_enum sd_bus_width_config(uint32_t buswidth)
     if(SD_BUS_WIDTH_1BIT == buswidth) {
         if(SD_ALLZERO != (sd_scr[1] & buswidth)) {
             /* send CMD55(APP_CMD) to indicate next command is application specific command */
+            sdio_csm_disable();
             sdio_command_response_config(SD_CMD_APP_CMD, (uint32_t)sd_rca << SD_RCA_SHIFT, SDIO_RESPONSETYPE_SHORT);
             sdio_wait_type_set(SDIO_WAITTYPE_NO);
             sdio_csm_enable();
@@ -2244,6 +2282,7 @@ static sd_error_enum sd_bus_width_config(uint32_t buswidth)
             }
 
             /* send ACMD6(SET_BUS_WIDTH) to define the data bus width */
+            sdio_csm_disable();
             sdio_command_response_config(SD_APPCMD_SET_BUS_WIDTH, (uint32_t)0x0, SDIO_RESPONSETYPE_SHORT);
             sdio_wait_type_set(SDIO_WAITTYPE_NO);
             sdio_csm_enable();
@@ -2259,6 +2298,7 @@ static sd_error_enum sd_bus_width_config(uint32_t buswidth)
     } else if(SD_BUS_WIDTH_4BIT == buswidth) {
         if(SD_ALLZERO != (sd_scr[1] & buswidth)) {
             /* send CMD55(APP_CMD) to indicate next command is application specific command */
+            sdio_csm_disable();
             sdio_command_response_config(SD_CMD_APP_CMD, (uint32_t)sd_rca << SD_RCA_SHIFT, SDIO_RESPONSETYPE_SHORT);
             sdio_wait_type_set(SDIO_WAITTYPE_NO);
             sdio_csm_enable();
@@ -2269,6 +2309,7 @@ static sd_error_enum sd_bus_width_config(uint32_t buswidth)
             }
 
             /* send ACMD6(SET_BUS_WIDTH) to define the data bus width */
+            sdio_csm_disable();
             sdio_command_response_config(SD_APPCMD_SET_BUS_WIDTH, (uint32_t)0x2, SDIO_RESPONSETYPE_SHORT);
             sdio_wait_type_set(SDIO_WAITTYPE_NO);
             sdio_csm_enable();
@@ -2298,6 +2339,7 @@ static sd_error_enum sd_scr_get(uint16_t rca, uint32_t *pscr)
     sd_error_enum status = SD_OK;
     uint32_t temp_scr[2] = {0, 0}, idx_scr = 0;
     /* send CMD16(SET_BLOCKLEN) to set block length */
+    sdio_csm_disable();
     sdio_command_response_config(SD_CMD_SET_BLOCKLEN, (uint32_t)8, SDIO_RESPONSETYPE_SHORT);
     sdio_wait_type_set(SDIO_WAITTYPE_NO);
     sdio_csm_enable();
@@ -2308,6 +2350,7 @@ static sd_error_enum sd_scr_get(uint16_t rca, uint32_t *pscr)
     }
 
     /* send CMD55(APP_CMD) to indicate next command is application specific command */
+    sdio_csm_disable();
     sdio_command_response_config(SD_CMD_APP_CMD, (uint32_t)rca << SD_RCA_SHIFT, SDIO_RESPONSETYPE_SHORT);
     sdio_wait_type_set(SDIO_WAITTYPE_NO);
     sdio_csm_enable();
@@ -2323,6 +2366,7 @@ static sd_error_enum sd_scr_get(uint16_t rca, uint32_t *pscr)
     sdio_dsm_enable();
 
     /* send ACMD51(SEND_SCR) to read the SD configuration register */
+    sdio_csm_disable();
     sdio_command_response_config(SD_APPCMD_SEND_SCR, (uint32_t)0x0, SDIO_RESPONSETYPE_SHORT);
     sdio_wait_type_set(SDIO_WAITTYPE_NO);
     sdio_csm_enable();