|
@@ -594,6 +594,7 @@ static int prism2_config(struct pcmcia_device *link)
|
|
local_info_t *local;
|
|
local_info_t *local;
|
|
int ret = 1;
|
|
int ret = 1;
|
|
struct hostap_cs_priv *hw_priv;
|
|
struct hostap_cs_priv *hw_priv;
|
|
|
|
+ unsigned long flags;
|
|
|
|
|
|
PDEBUG(DEBUG_FLOW, "prism2_config()\n");
|
|
PDEBUG(DEBUG_FLOW, "prism2_config()\n");
|
|
|
|
|
|
@@ -625,9 +626,15 @@ static int prism2_config(struct pcmcia_device *link)
|
|
local->hw_priv = hw_priv;
|
|
local->hw_priv = hw_priv;
|
|
hw_priv->link = link;
|
|
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);
|
|
ret = pcmcia_request_irq(link, prism2_interrupt);
|
|
if (ret)
|
|
if (ret)
|
|
- goto failed;
|
|
|
|
|
|
+ goto failed_unlock;
|
|
|
|
|
|
/*
|
|
/*
|
|
* This actually configures the PCMCIA socket -- setting up
|
|
* 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);
|
|
ret = pcmcia_request_configuration(link, &link->conf);
|
|
if (ret)
|
|
if (ret)
|
|
- goto failed;
|
|
|
|
|
|
+ goto failed_unlock;
|
|
|
|
|
|
dev->irq = link->irq;
|
|
dev->irq = link->irq;
|
|
dev->base_addr = link->io.BasePort1;
|
|
dev->base_addr = link->io.BasePort1;
|
|
|
|
|
|
|
|
+ spin_unlock_irqrestore(&local->irq_init_lock, flags);
|
|
|
|
+
|
|
/* Finally, report what we've done */
|
|
/* Finally, report what we've done */
|
|
printk(KERN_INFO "%s: index 0x%02x: ",
|
|
printk(KERN_INFO "%s: index 0x%02x: ",
|
|
dev_info, link->conf.ConfigIndex);
|
|
dev_info, link->conf.ConfigIndex);
|
|
@@ -667,6 +676,8 @@ static int prism2_config(struct pcmcia_device *link)
|
|
|
|
|
|
return ret;
|
|
return ret;
|
|
|
|
|
|
|
|
+ failed_unlock:
|
|
|
|
+ spin_unlock_irqrestore(&local->irq_init_lock, flags);
|
|
failed:
|
|
failed:
|
|
kfree(hw_priv);
|
|
kfree(hw_priv);
|
|
prism2_release((u_long)link);
|
|
prism2_release((u_long)link);
|