diff options
| author | Michael Buesch <mb@bu3sch.de> | 2006-06-17 09:19:05 -0400 |
|---|---|---|
| committer | Jeff Garzik <jeff@garzik.org> | 2006-07-05 13:42:57 -0400 |
| commit | a1d79aaaa564abc19b7bf3a024bb371fa7648a15 (patch) | |
| tree | 95824af615a33102a058ebc2500416b31aafc7ec | |
| parent | e8d596972221aea55ae7f5c2bb7d5895039f664d (diff) | |
[PATCH] bcm43xx: workaround init_board vs. IRQ race
Place the Init-vs-IRQ workaround before any card register
access, because we might not have the wireless core mapped
at all times in init. So this will result in a Machine Check
caused by a bus error.
Signed-off-by: Michael Buesch <mb@bu3sch.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
| -rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_main.c | 27 |
1 files changed, 14 insertions, 13 deletions
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index d8f5600578b4..673ab11d92ab 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c | |||
| @@ -1885,6 +1885,15 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re | |||
| 1885 | 1885 | ||
| 1886 | spin_lock(&bcm->irq_lock); | 1886 | spin_lock(&bcm->irq_lock); |
| 1887 | 1887 | ||
| 1888 | /* Only accept IRQs, if we are initialized properly. | ||
| 1889 | * This avoids an RX race while initializing. | ||
| 1890 | * We should probably not enable IRQs before we are initialized | ||
| 1891 | * completely, but some careful work is needed to fix this. I think it | ||
| 1892 | * is best to stay with this cheap workaround for now... . | ||
| 1893 | */ | ||
| 1894 | if (unlikely(bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)) | ||
| 1895 | goto out; | ||
| 1896 | |||
| 1888 | reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); | 1897 | reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); |
| 1889 | if (reason == 0xffffffff) { | 1898 | if (reason == 0xffffffff) { |
| 1890 | /* irq not for us (shared irq) */ | 1899 | /* irq not for us (shared irq) */ |
| @@ -1906,19 +1915,11 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re | |||
| 1906 | 1915 | ||
| 1907 | bcm43xx_interrupt_ack(bcm, reason); | 1916 | bcm43xx_interrupt_ack(bcm, reason); |
| 1908 | 1917 | ||
| 1909 | /* Only accept IRQs, if we are initialized properly. | 1918 | /* disable all IRQs. They are enabled again in the bottom half. */ |
| 1910 | * This avoids an RX race while initializing. | 1919 | bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); |
| 1911 | * We should probably not enable IRQs before we are initialized | 1920 | /* save the reason code and call our bottom half. */ |
| 1912 | * completely, but some careful work is needed to fix this. I think it | 1921 | bcm->irq_reason = reason; |
| 1913 | * is best to stay with this cheap workaround for now... . | 1922 | tasklet_schedule(&bcm->isr_tasklet); |
| 1914 | */ | ||
| 1915 | if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) { | ||
| 1916 | /* disable all IRQs. They are enabled again in the bottom half. */ | ||
| 1917 | bcm->irq_savedstate = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL); | ||
| 1918 | /* save the reason code and call our bottom half. */ | ||
| 1919 | bcm->irq_reason = reason; | ||
| 1920 | tasklet_schedule(&bcm->isr_tasklet); | ||
| 1921 | } | ||
| 1922 | 1923 | ||
| 1923 | out: | 1924 | out: |
| 1924 | mmiowb(); | 1925 | mmiowb(); |
