From 9ba85aa629fd2636a7a392033c7fac39324c6f0d Mon Sep 17 00:00:00 2001 From: Raja Mani Date: Mon, 21 Nov 2011 12:26:51 +0530 Subject: [PATCH] ath6kl: Use mutex to protect dma buffer in sync read write Firmware crashes while starting Soft AP in 32 bit x86 platform. The reason is that the single dma buffer (ar_sdio->dma_buffer) is used in ath6kl_sdio_read_write_sync() for unaligned buffer handling and this function is called in the multiple context at the same time. So, finally hits dma buffer corruption and firmware crash. Mutex is used to protect dma buffer to avoid data corruption. Spin lock can not used to fix this issue since mmc stack read/write calls may for sleep. Observed this issue with recently commited patch "ath6kl: Claim sdio function only at appropriate places" 1c7457a4fe4731bd93636f763ea083ac29ab247a kvalo: change name of mutex to more descriptive and add a comment about what it protects Signed-off-by: Raja Mani Signed-off-by: Kalle Valo --- drivers/net/wireless/ath/ath6kl/sdio.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c index b52b90d730db0..eecf88c43d0c5 100644 --- a/drivers/net/wireless/ath/ath6kl/sdio.c +++ b/drivers/net/wireless/ath/ath6kl/sdio.c @@ -39,8 +39,12 @@ struct ath6kl_sdio { struct bus_request bus_req[BUS_REQUEST_MAX_NUM]; struct ath6kl *ar; + u8 *dma_buffer; + /* protects access to dma_buffer */ + struct mutex dma_buffer_mutex; + /* scatter request list head */ struct list_head scat_req; @@ -395,6 +399,7 @@ static int ath6kl_sdio_read_write_sync(struct ath6kl *ar, u32 addr, u8 *buf, if (buf_needs_bounce(buf)) { if (!ar_sdio->dma_buffer) return -ENOMEM; + mutex_lock(&ar_sdio->dma_buffer_mutex); tbuf = ar_sdio->dma_buffer; memcpy(tbuf, buf, len); bounced = true; @@ -405,6 +410,9 @@ static int ath6kl_sdio_read_write_sync(struct ath6kl *ar, u32 addr, u8 *buf, if ((request & HIF_READ) && bounced) memcpy(buf, tbuf, len); + if (bounced) + mutex_unlock(&ar_sdio->dma_buffer_mutex); + return ret; } @@ -1219,6 +1227,7 @@ static int ath6kl_sdio_probe(struct sdio_func *func, spin_lock_init(&ar_sdio->lock); spin_lock_init(&ar_sdio->scat_lock); spin_lock_init(&ar_sdio->wr_async_lock); + mutex_init(&ar_sdio->dma_buffer_mutex); INIT_LIST_HEAD(&ar_sdio->scat_req); INIT_LIST_HEAD(&ar_sdio->bus_req_freeq); -- 2.39.5