Properly protect all accesses to maple_waitq or maple_sentq with maple_wlist_lock. Signed-off-by: Jörn Engel --- drivers/sh/maple/maple.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) --- maple/drivers/sh/maple/maple.c~cu7 2008-03-24 17:49:59.000000000 +0100 +++ maple/drivers/sh/maple/maple.c 2008-03-24 18:02:03.000000000 +0100 @@ -236,17 +236,13 @@ static void maple_send(void) int maple_packets; struct mapleq *mq, *nmq; - if (!list_empty(&maple_sentq)) - return; mutex_lock(&maple_wlist_lock); - if (list_empty(&maple_waitq) || !maple_dma_done()) { - mutex_unlock(&maple_wlist_lock); - return; - } - mutex_unlock(&maple_wlist_lock); + if (!list_empty(&maple_sentq)) + goto out; + if (list_empty(&maple_waitq) || !maple_dma_done()) + goto out; maple_packets = 0; maple_sendptr = maple_lastptr = maple_sendbuf; - mutex_lock(&maple_wlist_lock); list_for_each_entry_safe(mq, nmq, &maple_waitq, list) { maple_build_block(mq); list_move(&mq->list, &maple_sentq); @@ -259,6 +255,9 @@ static void maple_send(void) dma_cache_sync(0, maple_sendbuf + i * PAGE_SIZE, PAGE_SIZE, DMA_BIDIRECTIONAL); } + return; +out: + mutex_unlock(&maple_wlist_lock); } /* check if there is a driver registered likely to match this device */ @@ -401,24 +400,22 @@ setup_finished: /* VBLANK bottom half - implemented via workqueue */ static void maple_vblank_handler(struct work_struct *work) { + mutex_lock(&maple_wlist_lock); if (!list_empty(&maple_sentq)) - return; + goto out; if (!maple_dma_done()) - return; + goto out; ctrl_outl(0, MAPLE_ENABLE); bus_for_each_dev(&maple_bus_type, NULL, NULL, setup_maple_commands); if (time_after(jiffies, maple_pnp_time)) maple_pnp_time = jiffies + MAPLE_PNP_INTERVAL; - mutex_lock(&maple_wlist_lock); - if (!list_empty(&maple_waitq) && list_empty(&maple_sentq)) { - mutex_unlock(&maple_wlist_lock); + if (!list_empty(&maple_waitq) && list_empty(&maple_sentq)) maple_send(); - } else { - mutex_unlock(&maple_wlist_lock); - } maplebus_dma_reset(); +out: + mutex_unlock(&maple_wlist_lock); } /* handle devices added via hotplugs - placing them on queue for DEVINFO*/ @@ -540,6 +537,7 @@ static void maple_dma_handler(struct wor if (!maple_dma_done()) return; ctrl_outl(0, MAPLE_ENABLE); + mutex_lock(&maple_wlist_lock); if (!list_empty(&maple_sentq)) { list_for_each_entry_safe(mq, nmq, &maple_sentq, list) { recvbuf = mq->recvbuf; @@ -595,6 +593,7 @@ static void maple_dma_handler(struct wor if (started == 0) started = 1; } + mutex_unlock(&maple_wlist_lock); maplebus_dma_reset(); }