 
            As reported by Michael Garofalo, the b43 WLAN driver request a strict 64 byte block size because of FIFO limitations.
When the bounce buffer is active, all requests will be coalesced into bigger (up to 64KB) chunks, which breaks SDIO.
Fix this by checking if we are using an SDIO card, and in that case do not use the bounce buffer.
Link: https://lore.kernel.org/linux-mmc/20251006013700.2272166-1-officialTechflash... Cc: stable@vger.kernel.org Signed-off-by: Linus Walleij linus.walleij@linaro.org --- drivers/mmc/host/sdhci.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index ac7e11f37af71fa5a70eb579fd812227b9347f83..c349e5b507b63a5ee9a9dcb08ac95cae6b3d7075 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -650,6 +650,21 @@ static void sdhci_transfer_pio(struct sdhci_host *host) DBG("PIO transfer complete.\n"); }
+static bool sdhci_use_bounce_buffer(struct sdhci_host *host) +{ + /* + * Don't bounce SDIO messages: these need the block size + * to be strictly respected (FIFOs in the device). + */ + if (mmc_card_sdio(host->mmc->card)) + return false; + + if (host->bounce_buffer) + return true; + + return false; +} + static int sdhci_pre_dma_transfer(struct sdhci_host *host, struct mmc_data *data, int cookie) { @@ -663,7 +678,7 @@ static int sdhci_pre_dma_transfer(struct sdhci_host *host, return data->sg_count;
/* Bounce write requests to the bounce buffer */ - if (host->bounce_buffer) { + if (sdhci_use_bounce_buffer(host)) { unsigned int length = data->blksz * data->blocks;
if (length > host->bounce_buffer_size) { @@ -890,7 +905,7 @@ static void sdhci_set_adma_addr(struct sdhci_host *host, dma_addr_t addr)
static dma_addr_t sdhci_sdma_address(struct sdhci_host *host) { - if (host->bounce_buffer) + if (sdhci_use_bounce_buffer(host)) return host->bounce_addr; else return sg_dma_address(host->data->sg); @@ -3030,7 +3045,7 @@ static void sdhci_pre_req(struct mmc_host *mmc, struct mmc_request *mrq) * for that we would need two bounce buffers since one buffer is * in flight when this is getting called. */ - if (host->flags & SDHCI_REQ_USE_DMA && !host->bounce_buffer) + if (host->flags & SDHCI_REQ_USE_DMA && !sdhci_use_bounce_buffer(host)) sdhci_pre_dma_transfer(host, mrq->data, COOKIE_PRE_MAPPED); }
@@ -3104,7 +3119,7 @@ void sdhci_request_done_dma(struct sdhci_host *host, struct mmc_request *mrq) struct mmc_data *data = mrq->data;
if (data && data->host_cookie == COOKIE_MAPPED) { - if (host->bounce_buffer) { + if (sdhci_use_bounce_buffer(host)) { /* * On reads, copy the bounced data into the * sglist
--- base-commit: 3a8660878839faadb4f1a6dd72c3179c1df56787 change-id: 20251024-sdhci-bb-regression-a26822c56951
Best regards,