diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-22 22:15:09 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-22 22:15:09 -0700 |
commit | 065a3e17baa36d1d48eb7376138820035b44775e (patch) | |
tree | 556abb5dbeaad98fc5a66bd56f6a647dfbd22182 /drivers/net/wireless/ipw2200.c | |
parent | 45c091bb2d453ce4a8b06cf19872ec7a77fc4799 (diff) | |
parent | bfcbb00855db21dacd3c154ea13ec3fdd98e747b (diff) | |
download | linux-065a3e17baa36d1d48eb7376138820035b44775e.tar.gz linux-065a3e17baa36d1d48eb7376138820035b44775e.tar.bz2 linux-065a3e17baa36d1d48eb7376138820035b44775e.zip |
Merge branch 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
* 'upstream-linus' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6: (33 commits)
[PATCH] myri10ge - drop workaround pci_save_state() disabling MSI
[PATCH] myri10ge - drop workaround for the missing AER ext cap on nVidia CK804
via-velocity: the link is not correctly detected when the device starts
[PATCH] add b44 to maintainers
[PATCH] WAN: ioremap() failure checks in drivers
[PATCH] WAN: register_hdlc_device() doesn't need dev_alloc_name()
[PATCH] skb_padto()-area fixes in 8390, wavelan
[PATCH] make drivers/net/forcedeth.c:nv_update_pause() static
[PATCH] network driver for Hilscher netx
[PATCH] Dereference in tokenring/olympic.c
[PATCH] Array overrun in drivers/net/wireless/wavelan.c
[PATCH] Remove useless check in drivers/net/pcmcia/xirc2ps_cs.c
[PATCH] 8139cp: add ethtool eeprom support
[PATCH] 8139cp: fix eeprom read command length
[PATCH] b44: update b44 Kconfig entry
[PATCH] b44: update version to 1.01
[PATCH] b44: add wol for old nic
[PATCH] b44: add parameter
[PATCH] b44: add wol
[PATCH] b44: fix manual speed/duplex/autoneg settings
...
Diffstat (limited to 'drivers/net/wireless/ipw2200.c')
-rw-r--r-- | drivers/net/wireless/ipw2200.c | 41 |
1 files changed, 32 insertions, 9 deletions
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c index 39f82f219749..081a8999666e 100644 --- a/drivers/net/wireless/ipw2200.c +++ b/drivers/net/wireless/ipw2200.c @@ -533,7 +533,7 @@ static inline void ipw_clear_bit(struct ipw_priv *priv, u32 reg, u32 mask) ipw_write32(priv, reg, ipw_read32(priv, reg) & ~mask); } -static inline void ipw_enable_interrupts(struct ipw_priv *priv) +static inline void __ipw_enable_interrupts(struct ipw_priv *priv) { if (priv->status & STATUS_INT_ENABLED) return; @@ -541,7 +541,7 @@ static inline void ipw_enable_interrupts(struct ipw_priv *priv) ipw_write32(priv, IPW_INTA_MASK_R, IPW_INTA_MASK_ALL); } -static inline void ipw_disable_interrupts(struct ipw_priv *priv) +static inline void __ipw_disable_interrupts(struct ipw_priv *priv) { if (!(priv->status & STATUS_INT_ENABLED)) return; @@ -549,6 +549,24 @@ static inline void ipw_disable_interrupts(struct ipw_priv *priv) ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL); } +static inline void ipw_enable_interrupts(struct ipw_priv *priv) +{ + unsigned long flags; + + spin_lock_irqsave(&priv->irq_lock, flags); + __ipw_enable_interrupts(priv); + spin_unlock_irqrestore(&priv->irq_lock, flags); +} + +static inline void ipw_disable_interrupts(struct ipw_priv *priv) +{ + unsigned long flags; + + spin_lock_irqsave(&priv->irq_lock, flags); + __ipw_disable_interrupts(priv); + spin_unlock_irqrestore(&priv->irq_lock, flags); +} + #ifdef CONFIG_IPW2200_DEBUG static char *ipw_error_desc(u32 val) { @@ -1856,7 +1874,7 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) unsigned long flags; int rc = 0; - spin_lock_irqsave(&priv->lock, flags); + spin_lock_irqsave(&priv->irq_lock, flags); inta = ipw_read32(priv, IPW_INTA_RW); inta_mask = ipw_read32(priv, IPW_INTA_MASK_R); @@ -1865,6 +1883,10 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) /* Add any cached INTA values that need to be handled */ inta |= priv->isr_inta; + spin_unlock_irqrestore(&priv->irq_lock, flags); + + spin_lock_irqsave(&priv->lock, flags); + /* handle all the justifications for the interrupt */ if (inta & IPW_INTA_BIT_RX_TRANSFER) { ipw_rx(priv); @@ -1993,10 +2015,10 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) IPW_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled); } + spin_unlock_irqrestore(&priv->lock, flags); + /* enable all interrupts */ ipw_enable_interrupts(priv); - - spin_unlock_irqrestore(&priv->lock, flags); } #define IPW_CMD(x) case IPW_CMD_ ## x : return #x @@ -10460,7 +10482,7 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs) if (!priv) return IRQ_NONE; - spin_lock(&priv->lock); + spin_lock(&priv->irq_lock); if (!(priv->status & STATUS_INT_ENABLED)) { /* Shared IRQ */ @@ -10482,7 +10504,7 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs) } /* tell the device to stop sending interrupts */ - ipw_disable_interrupts(priv); + __ipw_disable_interrupts(priv); /* ack current interrupts */ inta &= (IPW_INTA_MASK_ALL & inta_mask); @@ -10493,11 +10515,11 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs) tasklet_schedule(&priv->irq_tasklet); - spin_unlock(&priv->lock); + spin_unlock(&priv->irq_lock); return IRQ_HANDLED; none: - spin_unlock(&priv->lock); + spin_unlock(&priv->irq_lock); return IRQ_NONE; } @@ -11477,6 +11499,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) #ifdef CONFIG_IPW2200_DEBUG ipw_debug_level = debug; #endif + spin_lock_init(&priv->irq_lock); spin_lock_init(&priv->lock); for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) INIT_LIST_HEAD(&priv->ibss_mac_hash[i]); |