From 80822e0e6ac19a8038d1370915ef9f3df47aa4a6 Mon Sep 17 00:00:00 2001 From: XazZ Date: Fri, 15 Feb 2008 17:22:24 +0100 Subject: [PATCH] fixed multiple bugs, including an ifconfig wlan%d up lockup bug various little changes like some coding-style changes --- acx.h | 1 - common.c | 27 +++++++++++++++++++-------- pci.c | 27 +++++++++++++++------------ 3 files changed, 34 insertions(+), 21 deletions(-) diff --git a/acx.h b/acx.h index c3c4700..8738290 100644 --- a/acx.h +++ b/acx.h @@ -1,5 +1,4 @@ #include -#include #include "acx_config.h" #include "acx_mac80211.h" #include "acx_struct.h" diff --git a/common.c b/common.c index d177de0..f804268 100644 --- a/common.c +++ b/common.c @@ -1797,12 +1797,15 @@ void acx_i_set_multicast_list(struct ieee80211_hw *hw, FN_ENTER; - acx_lock(adev, flags); + acx_lock(adev, flags); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) - *total_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI); - if ((changed_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) == 0) - return; + changed_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | + FIF_CONTROL | FIF_OTHER_BSS); + *total_flags &= (FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | + FIF_CONTROL | FIF_OTHER_BSS); +/* if ((changed_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) == 0) + return; */ #endif #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) @@ -2514,7 +2517,7 @@ void acx_l_process_rxbuf(acx_device_t * adev, rxbuffer_t * rxbuf) buf_len = RXBUF_BYTES_RCVD(adev, rxbuf); if (unlikely(acx_debug & L_DATA)) { - printk("rx: 802.11 buf[%u]: ", buf_len); + printk("rx: 802.11 buf[%u]: \n", buf_len); acx_dump_bytes(hdr, buf_len); } @@ -4025,10 +4028,13 @@ static void acx_s_after_interrupt_recalib(acx_device_t * adev) void acx_e_after_interrupt_task(struct work_struct *work) { - acx_device_t *adev = container_of(work, acx_device_t, after_interrupt_task); + acx_device_t *adev = container_of(work, acx_device_t, after_interrupt_task); unsigned long flags; + FN_ENTER; + acx_lock(adev, flags); + if (!adev->after_interrupt_jobs || !adev->initialized) goto end; /* no jobs to do */ @@ -4039,11 +4045,15 @@ void acx_e_after_interrupt_task(struct work_struct *work) /* a poor interrupt code wanted to do update_card_settings() */ if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_UPDATE_CARD_CFG) { - if (ACX_STATE_IFACE_UP & adev->dev_state_mask) + if (ACX_STATE_IFACE_UP & adev->dev_state_mask) { + acx_unlock(adev, flags); acx_s_update_card_settings(adev); + acx_lock(adev, flags); + } CLEAR_BIT(adev->after_interrupt_jobs, ACX_AFTER_IRQ_UPDATE_CARD_CFG); } + /* 1) we detected that no Scan_Complete IRQ came from fw, or ** 2) we found too many STAs */ if (adev->after_interrupt_jobs & ACX_AFTER_IRQ_CMD_STOP_SCAN) { @@ -4414,12 +4424,13 @@ int acx_net_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf) acx_lock(adev, flags); //FIXME(); if (!adev->initialized) { - acx_unlock(adev,flags); + acx_unlock(adev, flags); return 0; } if (conf->beacon_int != adev->beacon_interval) adev->beacon_interval = conf->beacon_int; if (conf->channel != adev->channel) { + acx_unlock(adev, flags); acx_selectchannel(adev, conf->channel,conf->freq); /* acx_schedule_task(adev, ACX_AFTER_IRQ_UPDATE_CARD_CFG diff --git a/pci.c b/pci.c index 808ffc5..cd33a86 100644 --- a/pci.c +++ b/pci.c @@ -938,7 +938,7 @@ int acxpci_s_reset_dev(acx_device_t * adev) } #endif /* scan, if any, is stopped now, setting corresponding IRQ bit */ - adev->irq_status |= HOST_INT_SCAN_COMPLETE; + SET_BIT(adev->irq_status, HOST_INT_SCAN_COMPLETE); acx_unlock(adev, flags); @@ -1038,7 +1038,6 @@ acxpci_s_issue_cmd_timeo_debug(acx_device_t * adev, FN_ENTER; - devname = wiphy_name(adev->ieee->wiphy); if (!devname || !devname[0] || devname[4] == '%') devname = "acx"; @@ -1114,11 +1113,10 @@ acxpci_s_issue_cmd_timeo_debug(acx_device_t * adev, if (unlikely(cmd_timeout > 1199)) cmd_timeout = 1199; /* clear CMD_COMPLETE bit. can be set only by IRQ handler: */ - adev->irq_status &= ~HOST_INT_CMD_COMPLETE; - + CLEAR_BIT(adev->irq_status, HOST_INT_CMD_COMPLETE); /* we schedule away sometimes (timeout can be large) */ counter = cmd_timeout; - timeout = jiffies + cmd_timeout * HZ / 1000; + timeout = jiffies + HZ; do { if (!adev->irqs_active) { /* IRQ disabled: poll */ irqtype = read_reg16(adev, IO_ACX_IRQ_STATUS_NON_DES); @@ -2041,16 +2039,15 @@ static void disable_acx_irq(acx_device_t * adev) static void acxpci_s_down(struct ieee80211_hw *hw) { acx_device_t *adev = ieee2adev(hw); - unsigned long flags; FN_ENTER; /* Disable IRQs first, so that IRQs cannot race with us */ /* then wait until interrupts have finished executing on other CPUs */ - acx_lock(adev, flags); + acx_sem_lock(adev); disable_acx_irq(adev); synchronize_irq(adev->irq); - acx_unlock(adev, flags); + acx_sem_unlock(adev); /* we really don't want to have an asynchronous tasklet disturb us ** after something vital for its job has been shut down, so @@ -2175,8 +2172,11 @@ static void acxpci_e_close(struct ieee80211_hw *hw) #endif { acx_device_t *adev = ieee2adev(hw); + FN_ENTER; + acx_sem_lock(adev); + /* ifdown device */ CLEAR_BIT(adev->dev_state_mask, ACX_STATE_IFACE_UP); if (adev->initialized) { @@ -2583,21 +2583,22 @@ acxpci_i_interrupt(int irq, void *dev_id) acxpci_i_interrupt(int irq, void *dev_id, struct pt_regs *regs) #endif { - acx_device_t *adev = dev_id; unsigned long flags; register u16 irqtype; u16 unmasked; + FN_ENTER; + if (!adev) return IRQ_NONE; + /* LOCKING: can just spin_lock() since IRQs are disabled anyway. * I am paranoid */ acx_lock(adev, flags); unmasked = read_reg16(adev, IO_ACX_IRQ_STATUS_CLEAR); - if (unlikely(0xffff == unmasked)) { /* 0xffff value hints at missing hardware, * so don't do anything. @@ -2638,10 +2639,13 @@ acxpci_i_interrupt(int irq, void *dev_id, struct pt_regs *regs) if ((irqtype & HOST_INT_RX_COMPLETE) || (irqtype & HOST_INT_TX_COMPLETE)) acx_schedule_task(adev, 0); } + acx_unlock(adev, flags); + FN_EXIT0; return IRQ_HANDLED; none: acx_unlock(adev, flags); + FN_EXIT0; return IRQ_NONE; } @@ -3511,8 +3515,7 @@ static void *allocate(acx_device_t * adev, size_t size, dma_addr_t * phy, { void *ptr; - ptr = dma_alloc_coherent(adev->pdev ? adev->bus_dev : NULL, - size, phy, GFP_KERNEL); + ptr = dma_alloc_coherent(adev->bus_dev, size, phy, GFP_KERNEL); if (ptr) { log(L_DEBUG, "%s sz=%d adr=0x%p phy=0x%08llx\n", -- 2.11.4.GIT