diff options
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) | |||
| 533 | ipw_write32(priv, reg, ipw_read32(priv, reg) & ~mask); | 533 | ipw_write32(priv, reg, ipw_read32(priv, reg) & ~mask); |
| 534 | } | 534 | } |
| 535 | 535 | ||
| 536 | static inline void ipw_enable_interrupts(struct ipw_priv *priv) | 536 | static inline void __ipw_enable_interrupts(struct ipw_priv *priv) |
| 537 | { | 537 | { |
| 538 | if (priv->status & STATUS_INT_ENABLED) | 538 | if (priv->status & STATUS_INT_ENABLED) |
| 539 | return; | 539 | return; |
| @@ -541,7 +541,7 @@ static inline void ipw_enable_interrupts(struct ipw_priv *priv) | |||
| 541 | ipw_write32(priv, IPW_INTA_MASK_R, IPW_INTA_MASK_ALL); | 541 | ipw_write32(priv, IPW_INTA_MASK_R, IPW_INTA_MASK_ALL); |
| 542 | } | 542 | } |
| 543 | 543 | ||
| 544 | static inline void ipw_disable_interrupts(struct ipw_priv *priv) | 544 | static inline void __ipw_disable_interrupts(struct ipw_priv *priv) |
| 545 | { | 545 | { |
| 546 | if (!(priv->status & STATUS_INT_ENABLED)) | 546 | if (!(priv->status & STATUS_INT_ENABLED)) |
| 547 | return; | 547 | return; |
| @@ -549,6 +549,24 @@ static inline void ipw_disable_interrupts(struct ipw_priv *priv) | |||
| 549 | ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL); | 549 | ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL); |
| 550 | } | 550 | } |
| 551 | 551 | ||
| 552 | static inline void ipw_enable_interrupts(struct ipw_priv *priv) | ||
| 553 | { | ||
| 554 | unsigned long flags; | ||
| 555 | |||
| 556 | spin_lock_irqsave(&priv->irq_lock, flags); | ||
| 557 | __ipw_enable_interrupts(priv); | ||
| 558 | spin_unlock_irqrestore(&priv->irq_lock, flags); | ||
| 559 | } | ||
| 560 | |||
| 561 | static inline void ipw_disable_interrupts(struct ipw_priv *priv) | ||
| 562 | { | ||
| 563 | unsigned long flags; | ||
| 564 | |||
| 565 | spin_lock_irqsave(&priv->irq_lock, flags); | ||
| 566 | __ipw_disable_interrupts(priv); | ||
| 567 | spin_unlock_irqrestore(&priv->irq_lock, flags); | ||
| 568 | } | ||
| 569 | |||
| 552 | #ifdef CONFIG_IPW2200_DEBUG | 570 | #ifdef CONFIG_IPW2200_DEBUG |
| 553 | static char *ipw_error_desc(u32 val) | 571 | static char *ipw_error_desc(u32 val) |
| 554 | { | 572 | { |
| @@ -1856,7 +1874,7 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) | |||
| 1856 | unsigned long flags; | 1874 | unsigned long flags; |
| 1857 | int rc = 0; | 1875 | int rc = 0; |
| 1858 | 1876 | ||
| 1859 | spin_lock_irqsave(&priv->lock, flags); | 1877 | spin_lock_irqsave(&priv->irq_lock, flags); |
| 1860 | 1878 | ||
| 1861 | inta = ipw_read32(priv, IPW_INTA_RW); | 1879 | inta = ipw_read32(priv, IPW_INTA_RW); |
| 1862 | inta_mask = ipw_read32(priv, IPW_INTA_MASK_R); | 1880 | inta_mask = ipw_read32(priv, IPW_INTA_MASK_R); |
| @@ -1865,6 +1883,10 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) | |||
| 1865 | /* Add any cached INTA values that need to be handled */ | 1883 | /* Add any cached INTA values that need to be handled */ |
| 1866 | inta |= priv->isr_inta; | 1884 | inta |= priv->isr_inta; |
| 1867 | 1885 | ||
| 1886 | spin_unlock_irqrestore(&priv->irq_lock, flags); | ||
| 1887 | |||
| 1888 | spin_lock_irqsave(&priv->lock, flags); | ||
| 1889 | |||
| 1868 | /* handle all the justifications for the interrupt */ | 1890 | /* handle all the justifications for the interrupt */ |
| 1869 | if (inta & IPW_INTA_BIT_RX_TRANSFER) { | 1891 | if (inta & IPW_INTA_BIT_RX_TRANSFER) { |
| 1870 | ipw_rx(priv); | 1892 | ipw_rx(priv); |
| @@ -1993,10 +2015,10 @@ static void ipw_irq_tasklet(struct ipw_priv *priv) | |||
| 1993 | IPW_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled); | 2015 | IPW_ERROR("Unhandled INTA bits 0x%08x\n", inta & ~handled); |
| 1994 | } | 2016 | } |
| 1995 | 2017 | ||
| 2018 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 2019 | |||
| 1996 | /* enable all interrupts */ | 2020 | /* enable all interrupts */ |
| 1997 | ipw_enable_interrupts(priv); | 2021 | ipw_enable_interrupts(priv); |
| 1998 | |||
| 1999 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 2000 | } | 2022 | } |
| 2001 | 2023 | ||
| 2002 | #define IPW_CMD(x) case IPW_CMD_ ## x : return #x | 2024 | #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) | |||
| 10460 | if (!priv) | 10482 | if (!priv) |
| 10461 | return IRQ_NONE; | 10483 | return IRQ_NONE; |
| 10462 | 10484 | ||
| 10463 | spin_lock(&priv->lock); | 10485 | spin_lock(&priv->irq_lock); |
| 10464 | 10486 | ||
| 10465 | if (!(priv->status & STATUS_INT_ENABLED)) { | 10487 | if (!(priv->status & STATUS_INT_ENABLED)) { |
| 10466 | /* Shared IRQ */ | 10488 | /* Shared IRQ */ |
| @@ -10482,7 +10504,7 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs) | |||
| 10482 | } | 10504 | } |
| 10483 | 10505 | ||
| 10484 | /* tell the device to stop sending interrupts */ | 10506 | /* tell the device to stop sending interrupts */ |
| 10485 | ipw_disable_interrupts(priv); | 10507 | __ipw_disable_interrupts(priv); |
| 10486 | 10508 | ||
| 10487 | /* ack current interrupts */ | 10509 | /* ack current interrupts */ |
| 10488 | inta &= (IPW_INTA_MASK_ALL & inta_mask); | 10510 | inta &= (IPW_INTA_MASK_ALL & inta_mask); |
| @@ -10493,11 +10515,11 @@ static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs) | |||
| 10493 | 10515 | ||
| 10494 | tasklet_schedule(&priv->irq_tasklet); | 10516 | tasklet_schedule(&priv->irq_tasklet); |
| 10495 | 10517 | ||
| 10496 | spin_unlock(&priv->lock); | 10518 | spin_unlock(&priv->irq_lock); |
| 10497 | 10519 | ||
| 10498 | return IRQ_HANDLED; | 10520 | return IRQ_HANDLED; |
| 10499 | none: | 10521 | none: |
| 10500 | spin_unlock(&priv->lock); | 10522 | spin_unlock(&priv->irq_lock); |
| 10501 | return IRQ_NONE; | 10523 | return IRQ_NONE; |
| 10502 | } | 10524 | } |
| 10503 | 10525 | ||
| @@ -11477,6 +11499,7 @@ static int ipw_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 11477 | #ifdef CONFIG_IPW2200_DEBUG | 11499 | #ifdef CONFIG_IPW2200_DEBUG |
| 11478 | ipw_debug_level = debug; | 11500 | ipw_debug_level = debug; |
| 11479 | #endif | 11501 | #endif |
| 11502 | spin_lock_init(&priv->irq_lock); | ||
| 11480 | spin_lock_init(&priv->lock); | 11503 | spin_lock_init(&priv->lock); |
| 11481 | for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) | 11504 | for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) |
| 11482 | INIT_LIST_HEAD(&priv->ibss_mac_hash[i]); | 11505 | INIT_LIST_HEAD(&priv->ibss_mac_hash[i]); |
