Skip to content

Commit

Permalink
ath6kl: Use mutex to protect dma buffer in sync read write
Browse files Browse the repository at this point in the history
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"
861dd05

kvalo: change name of mutex to more descriptive and add a comment
about what it protects

Signed-off-by: Raja Mani <rmani@qca.qualcomm.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
  • Loading branch information
Raja Mani authored and Kalle Valo committed Nov 21, 2011
1 parent 743b451 commit fdb2858
Showing 1 changed file with 9 additions and 0 deletions.
9 changes: 9 additions & 0 deletions drivers/net/wireless/ath/ath6kl/sdio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand All @@ -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;
}

Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit fdb2858

Please sign in to comment.