summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/hostap/hostap_cs.c
diff options
context:
space:
mode:
authorTim Gardner <tim.gardner@canonical.com>2010-06-08 21:33:02 +0400
committerJohn W. Linville <linville@tuxdriver.com>2010-06-15 23:44:41 +0400
commitd6a574ff6bfb842bdb98065da053881ff527be46 (patch)
tree899cdc5cdfc75d21a8c258ecfc2bc6b1e1c79895 /drivers/net/wireless/hostap/hostap_cs.c
parenta69b03e941abae00380fc6bc1877fb797a1b31e6 (diff)
downloadlinux-d6a574ff6bfb842bdb98065da053881ff527be46.tar.xz
hostap: Protect against initialization interrupt
Use an irq spinlock to hold off the IRQ handler until enough early card init is complete such that the handler can run without faulting. Signed-off-by: Tim Gardner <tim.gardner@canonical.com> Cc: stable@kernel.org Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/hostap/hostap_cs.c')
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index db72461c486b..29b31a694b59 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -594,6 +594,7 @@ static int prism2_config(struct pcmcia_device *link)
local_info_t *local;
int ret = 1;
struct hostap_cs_priv *hw_priv;
+ unsigned long flags;
PDEBUG(DEBUG_FLOW, "prism2_config()\n");
@@ -625,9 +626,15 @@ static int prism2_config(struct pcmcia_device *link)
local->hw_priv = hw_priv;
hw_priv->link = link;
+ /*
+ * Make sure the IRQ handler cannot proceed until at least
+ * dev->base_addr is initialized.
+ */
+ spin_lock_irqsave(&local->irq_init_lock, flags);
+
ret = pcmcia_request_irq(link, prism2_interrupt);
if (ret)
- goto failed;
+ goto failed_unlock;
/*
* This actually configures the PCMCIA socket -- setting up
@@ -636,11 +643,13 @@ static int prism2_config(struct pcmcia_device *link)
*/
ret = pcmcia_request_configuration(link, &link->conf);
if (ret)
- goto failed;
+ goto failed_unlock;
dev->irq = link->irq;
dev->base_addr = link->io.BasePort1;
+ spin_unlock_irqrestore(&local->irq_init_lock, flags);
+
/* Finally, report what we've done */
printk(KERN_INFO "%s: index 0x%02x: ",
dev_info, link->conf.ConfigIndex);
@@ -667,6 +676,8 @@ static int prism2_config(struct pcmcia_device *link)
return ret;
+ failed_unlock:
+ spin_unlock_irqrestore(&local->irq_init_lock, flags);
failed:
kfree(hw_priv);
prism2_release((u_long)link);