diff --git a/Kernel/Storage/SD/Registers.h b/Kernel/Storage/SD/Registers.h index bb22e09dfd..b88601fddd 100644 --- a/Kernel/Storage/SD/Registers.h +++ b/Kernel/Storage/SD/Registers.h @@ -38,7 +38,40 @@ struct HostControlRegisterMap { u32 present_state; u32 host_configuration_0; u32 host_configuration_1; - u32 interrupt_status; + union InterruptStatus { + struct { // SDHC 2.2.18 Normal Interrupt Status Register (Cat.C Offset 030h) + u32 command_complete : 1; + u32 transfer_complete : 1; + u32 block_gap_event : 1; + u32 dma_interrupt : 1; + u32 buffer_write_ready : 1; + u32 buffer_read_ready : 1; + u32 card_insertion : 1; + u32 card_removal : 1; + u32 card_interrupt : 1; + u32 int_a : 1; + u32 int_b : 1; + u32 int_c : 1; + u32 retuning_event : 1; + u32 fx_event : 1; + u32 : 1; + u32 error_interrupt : 1; + // SDHC 2.2.19 Error Interrupt Status Register (Cat.C Offset 032 + u32 command_timeout_error : 1; + u32 command_crc_error : 1; + u32 cammand_index_error : 1; + u32 data_timeout_error : 1; + u32 data_crc_error : 1; + u32 data_end_bit_error : 1; + u32 current_limit_error : 1; + u32 auto_cmd_error : 1; + u32 adma_error : 1; + u32 tuning_error : 1; + u32 response_error : 1; + u32 vendor_specific_error : 1; + }; + u32 raw; + } interrupt_status; u32 interrupt_status_enable; u32 interrupt_signal_enable; u32 host_configuration_2; diff --git a/Kernel/Storage/SD/SDHostController.cpp b/Kernel/Storage/SD/SDHostController.cpp index 842856c74a..b0bdbed3f3 100644 --- a/Kernel/Storage/SD/SDHostController.cpp +++ b/Kernel/Storage/SD/SDHostController.cpp @@ -276,12 +276,12 @@ ErrorOr SDHostController::wait_for_response() // 1. Wait for the Command Complete Interrupt. If the Command Complete // Interrupt has occurred, go to step (2). if (!retry_with_timeout( - [&]() { return m_registers->interrupt_status & command_complete; })) { + [&]() { return m_registers->interrupt_status.command_complete; })) { return EIO; } // 2. Write 1 to Command Complete in the Normal Interrupt Status register to clear this bit - m_registers->interrupt_status = command_complete; + m_registers->interrupt_status.raw = command_complete; // 3. Read the Response register(s) to get the response. // NOTE: We read fewer bits than ResponseType because the missing bits are only @@ -483,14 +483,13 @@ ErrorOr SDHostController::transaction_control_with_data_transfer_using_the m_registers->transfer_mode_and_command = command.raw; // 6. Then, wait for the Command Complete Interrupt. - if (!retry_with_timeout( - [&]() { return m_registers->interrupt_status & command_complete; })) { + if (!retry_with_timeout([&]() { return m_registers->interrupt_status.command_complete; })) { return EIO; } // 7. Write 1 to the Command Complete in the Normal Interrupt Status // register for clearing this bit. - m_registers->interrupt_status = command_complete; + m_registers->interrupt_status.raw = command_complete; // 8. Read Response register and get necessary information of the issued // command @@ -505,13 +504,13 @@ ErrorOr SDHostController::transaction_control_with_data_transfer_using_the // 10. Then wait for Buffer Write Ready Interrupt. if (!retry_with_timeout( [&]() { - return m_registers->interrupt_status & buffer_write_ready; + return m_registers->interrupt_status.buffer_write_ready; })) { return EIO; } // 11. Write 1 to the Buffer Write Ready in the Normal Interrupt Status register for clearing this bit. - m_registers->interrupt_status = buffer_write_ready; + m_registers->interrupt_status.raw = buffer_write_ready; // 12. Write block data (in according to the number of bytes specified at the step (1)) to Buffer Data Port register. u32 temp; @@ -525,13 +524,13 @@ ErrorOr SDHostController::transaction_control_with_data_transfer_using_the } else { for (u32 i = 0; i < block_count; i++) { // 14. Then wait for the Buffer Read Ready Interrupt. - if (!retry_with_timeout([&]() { return m_registers->interrupt_status & buffer_read_ready; })) { + if (!retry_with_timeout([&]() { return m_registers->interrupt_status.buffer_read_ready; })) { return EIO; } // 15. Write 1 to the Buffer Read Ready in the Normal Interrupt Status // register for clearing this bit. - m_registers->interrupt_status = buffer_read_ready; + m_registers->interrupt_status.raw = buffer_read_ready; // 16. Read block data (in according to the number of bytes specified at // the step (1)) from the Buffer Data Port register @@ -550,14 +549,13 @@ ErrorOr SDHostController::transaction_control_with_data_transfer_using_the // 19. Wait for Transfer Complete Interrupt. if (!retry_with_timeout( - [&]() { return m_registers->interrupt_status & transfer_complete; })) { + [&]() { return m_registers->interrupt_status.transfer_complete; })) { return EIO; } // 20. Write 1 to the Transfer Complete in the Normal Interrupt Status // register for clearing this bit - m_registers->interrupt_status = transfer_complete; - + m_registers->interrupt_status.raw = transfer_complete; return {}; }