Merge branch 'bugfix/sdio_slave_buffer_size_limit_v5.2' into 'release/v5.2'

fix(sdio_slave): align buffer size checks with descriptor limits (v5.2)

See merge request espressif/esp-idf!49903
This commit is contained in:
morris
2026-06-23 11:45:18 +08:00
6 changed files with 19 additions and 9 deletions
@@ -25,11 +25,13 @@ typedef struct {
sdio_slave_sending_mode_t sending_mode; ///< mode of sdio_slave. `SDIO_SLAVE_MODE_STREAM` if the data needs to be sent as much as possible; `SDIO_SLAVE_MODE_PACKET` if the data should be sent in packets.
int send_queue_size; ///< max buffers that can be queued before sending.
size_t recv_buffer_size;
///< If buffer_size is too small, it costs more CPU time to handle larger number of buffers.
///< If buffer_size is too large, the space larger than the transaction length is left blank but still counts a buffer, and the buffers are easily run out.
///< Should be set according to length of data really transferred.
///< All data that do not fully fill a buffer is still counted as one buffer. E.g. 10 bytes data costs 2 buffers if the size is 8 bytes per buffer.
///< Buffer size of the slave pre-defined between host and slave before communication. All receive buffer given to the driver should be larger than this.
///< If buffer_size is too small, it costs more CPU time to handle larger number of buffers.
///< If buffer_size is too large, the space larger than the transaction length is left blank but still counts a buffer, and the buffers are easily run out.
///< Should be set according to length of data really transferred.
///< All data that do not fully fill a buffer is still counted as one buffer. E.g. 10 bytes data costs 2 buffers if the size is 8 bytes per buffer.
///< Buffer size of the slave pre-defined between host and slave before communication. It must not exceed the
///< maximum size supported by a single SDIO slave DMA descriptor on the current chip,
///< and all receive buffer given to the driver should be larger than this.
sdio_event_cb_t event_cb; ///< when the host interrupts slave, this callback will be called with interrupt number (0-7).
uint32_t flags; ///< Features to be enabled for the slave, combinations of ``SDIO_SLAVE_FLAG_*``.
#define SDIO_SLAVE_FLAG_DAT2_DISABLED BIT(0) /**< It is required by the SD specification that all 4 data
@@ -186,7 +188,7 @@ uint8_t* sdio_slave_recv_get_buf(sdio_slave_buf_handle_t handle, size_t *len_o);
* ``sdio_slave_send_get_finished`` after the transaction is finished.
*
* @param addr Address for data to be sent. The buffer should be DMA capable and 32-bit aligned.
* @param len Length of the data, should not be longer than 4092 bytes (may support longer in the future).
* @param len Length of the data, should not exceed the maximum size supported by a single SDIO slave DMA descriptor on the current chip.
* @param arg Argument to returned in ``sdio_slave_send_get_finished``. The argument can be used to indicate which transaction is done,
* or as a parameter for a callback. Set to NULL if not needed.
* @param wait Time to wait if the buffer is full.
+3 -1
View File
@@ -92,6 +92,7 @@ The driver of FIFOs works as below:
#include "hal/sdio_slave_hal.h"
#include "hal/gpio_hal.h"
#define SDIO_SLAVE_DMA_DESC_MAX_BUF_SIZE_ALIGNED_DOWN (SDIO_SLAVE_LL_DMA_DESC_MAX_BUF_SIZE & ~0x3U)
#define SDIO_SLAVE_CHECK(res, str, ret_val) do { if(!(res)){\
SDIO_SLAVE_LOGE("%s", str);\
@@ -583,7 +584,8 @@ static void sdio_intr_send(void *arg)
esp_err_t sdio_slave_send_queue(uint8_t *addr, size_t len, void *arg, TickType_t wait)
{
SDIO_SLAVE_CHECK(len > 0 && len <= 4092, "length out of range: (0, 4092]", ESP_ERR_INVALID_ARG);
SDIO_SLAVE_CHECK(len > 0 && len <= SDIO_SLAVE_DMA_DESC_MAX_BUF_SIZE_ALIGNED_DOWN,
"length out of range for a single DMA descriptor", ESP_ERR_INVALID_ARG);
SDIO_SLAVE_CHECK(esp_ptr_dma_capable(addr) && (uint32_t)addr % 4 == 0, "buffer to send should be DMA capable and 32-bit aligned",
ESP_ERR_INVALID_ARG);
@@ -63,6 +63,9 @@ typedef struct sdio_slave_ll_desc_s {
};
} sdio_slave_ll_desc_t;
/* Maximum buffer size that a single SDIO slave DMA descriptor can point to. */
#define SDIO_SLAVE_LL_DMA_DESC_MAX_BUF_SIZE ((1 << 12) - 1)
/// Mask of general purpose interrupts sending from the host.
typedef enum {
SDIO_SLAVE_LL_SLVINT_0 = BIT(0), ///< General purpose interrupt bit 0.
@@ -63,6 +63,9 @@ typedef struct sdio_slave_ll_desc_s {
};
} sdio_slave_ll_desc_t;
/* Maximum buffer size that a single SDIO slave DMA descriptor can point to. */
#define SDIO_SLAVE_LL_DMA_DESC_MAX_BUF_SIZE ((1 << 14) - 1)
/// Mask of general purpose interrupts sending from the host.
typedef enum {
SDIO_SLAVE_LL_SLVINT_0 = BIT(0), ///< General purpose interrupt bit 0.