 
            On 24/10/2025 11:40, Linus Walleij wrote:
As reported by Michael Garofalo, the b43 WLAN driver request a strict 64 byte block size because of FIFO limitations.
Thanks a lot for looking at this!
When the bounce buffer is active, all requests will be coalesced into bigger (up to 64KB) chunks, which breaks SDIO.
Thing is, I cannot see any use of max_segs or anything else that would affect the request size.
Michael, are you using the upstream SDIO/Wifi drivers?
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;
sdhci_allocate_bounce_buffer() has still amended
mmc->max_segs = max_blocks; mmc->max_seg_size = bounce_size; mmc->max_req_size = bounce_size;
- 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,