summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2009-02-20 12:27:38 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-02-27 14:52:51 -0500
commit9b02f419a7dbd956b2c293e5cb1790b6b687f367 (patch)
tree63fb91f39f5fc43a64728cfe18fc89f1a77c28e5
parent25d3ef59a2112d50e145500e1bc764f9e8fd4896 (diff)
libertas: use private SDIO workqueue to avoid scheduling latency
The libertas SDIO interface scheduled the packet worker, resulting in unwanted latency for every data packet or command sent to the firmware. Fix a bug on the SDIO probe error path too. Signed-off-by: Dan Williams <dcbw@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/libertas/if_sdio.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c
index 987836865ea..76f4c653d64 100644
--- a/drivers/net/wireless/libertas/if_sdio.c
+++ b/drivers/net/wireless/libertas/if_sdio.c
@@ -95,6 +95,8 @@ struct if_sdio_card {
spinlock_t lock;
struct if_sdio_packet *packets;
+
+ struct workqueue_struct *workqueue;
struct work_struct packet_worker;
};
@@ -746,7 +748,7 @@ static int if_sdio_host_to_card(struct lbs_private *priv,
spin_unlock_irqrestore(&card->lock, flags);
- schedule_work(&card->packet_worker);
+ queue_work(card->workqueue, &card->packet_worker);
ret = 0;
@@ -836,6 +838,7 @@ static int if_sdio_probe(struct sdio_func *func,
card->func = func;
card->model = model;
spin_lock_init(&card->lock);
+ card->workqueue = create_workqueue("libertas_sdio");
INIT_WORK(&card->packet_worker, if_sdio_host_to_card_worker);
for (i = 0;i < ARRAY_SIZE(if_sdio_models);i++) {
@@ -933,9 +936,8 @@ out:
return ret;
err_activate_card:
- flush_scheduled_work();
- free_netdev(priv->dev);
- kfree(priv);
+ flush_workqueue(card->workqueue);
+ lbs_remove_card(priv);
reclaim:
sdio_claim_host(func);
release_int:
@@ -945,6 +947,7 @@ disable:
release:
sdio_release_host(func);
free:
+ destroy_workqueue(card->workqueue);
while (card->packets) {
packet = card->packets;
card->packets = card->packets->next;
@@ -971,7 +974,8 @@ static void if_sdio_remove(struct sdio_func *func)
lbs_stop_card(card->priv);
lbs_remove_card(card->priv);
- flush_scheduled_work();
+ flush_workqueue(card->workqueue);
+ destroy_workqueue(card->workqueue);
sdio_claim_host(func);
sdio_release_irq(func);