diff options
Diffstat (limited to 'drivers/net/wireless/b43')
-rw-r--r-- | drivers/net/wireless/b43/Kconfig | 10 | ||||
-rw-r--r-- | drivers/net/wireless/b43/debugfs.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/b43/main.c | 19 | ||||
-rw-r--r-- | drivers/net/wireless/b43/pcmcia.c | 52 | ||||
-rw-r--r-- | drivers/net/wireless/b43/rfkill.c | 115 | ||||
-rw-r--r-- | drivers/net/wireless/b43/rfkill.h | 14 |
6 files changed, 106 insertions, 106 deletions
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig index e3c573e56b63..fdbc351ac333 100644 --- a/drivers/net/wireless/b43/Kconfig +++ b/drivers/net/wireless/b43/Kconfig @@ -61,16 +61,18 @@ config B43_PCMCIA If unsure, say N. -# LED support +# This config option automatically enables b43 LEDS support, +# if it's possible. config B43_LEDS bool - depends on B43 && MAC80211_LEDS + depends on B43 && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = B43) default y -# RFKILL support +# This config option automatically enables b43 RFKILL support, +# if it's possible. config B43_RFKILL bool - depends on B43 && RFKILL && RFKILL_INPUT && INPUT_POLLDEV + depends on B43 && (RFKILL = y || RFKILL = B43) && RFKILL_INPUT && (INPUT_POLLDEV = y || INPUT_POLLDEV = B43) default y config B43_DEBUG diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c index 734e70e1a06d..ef0075d9f9cb 100644 --- a/drivers/net/wireless/b43/debugfs.c +++ b/drivers/net/wireless/b43/debugfs.c @@ -128,7 +128,7 @@ static ssize_t shm_read_file(struct b43_wldev *dev, __le16 *le16buf = (__le16 *)buf; for (i = 0; i < 0x1000; i++) { - if (bufsize <= 0) + if (bufsize < sizeof(tmp)) break; tmp = b43_shm_read16(dev, B43_SHM_SHARED, 2 * i); le16buf[i] = cpu_to_le16(tmp); diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 5058e60e5703..2b17c1dc46f1 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -2985,6 +2985,16 @@ static void b43_wireless_core_stop(struct b43_wldev *dev) if (b43_status(dev) < B43_STAT_STARTED) return; + + /* Disable and sync interrupts. We must do this before than + * setting the status to INITIALIZED, as the interrupt handler + * won't care about IRQs then. */ + spin_lock_irqsave(&wl->irq_lock, flags); + dev->irq_savedstate = b43_interrupt_disable(dev, B43_IRQ_ALL); + b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* flush */ + spin_unlock_irqrestore(&wl->irq_lock, flags); + b43_synchronize_irq(dev); + b43_set_status(dev, B43_STAT_INITIALIZED); mutex_unlock(&wl->mutex); @@ -2995,13 +3005,6 @@ static void b43_wireless_core_stop(struct b43_wldev *dev) ieee80211_stop_queues(wl->hw); //FIXME this could cause a deadlock, as mac80211 seems buggy. - /* Disable and sync interrupts. */ - spin_lock_irqsave(&wl->irq_lock, flags); - dev->irq_savedstate = b43_interrupt_disable(dev, B43_IRQ_ALL); - b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* flush */ - spin_unlock_irqrestore(&wl->irq_lock, flags); - b43_synchronize_irq(dev); - b43_mac_suspend(dev); free_irq(dev->dev->irq, dev); b43dbg(wl, "Wireless interface stopped\n"); @@ -3661,7 +3664,6 @@ static int b43_setup_modes(struct b43_wldev *dev, static void b43_wireless_core_detach(struct b43_wldev *dev) { - b43_rfkill_free(dev); /* We release firmware that late to not be required to re-request * is all the time when we reinit the core. */ b43_release_firmware(dev); @@ -3747,7 +3749,6 @@ static int b43_wireless_core_attach(struct b43_wldev *dev) if (!wl->current_dev) wl->current_dev = dev; INIT_WORK(&dev->restart_work, b43_chip_reset); - b43_rfkill_alloc(dev); b43_radio_turn_off(dev, 1); b43_switch_analog(dev, 0); diff --git a/drivers/net/wireless/b43/pcmcia.c b/drivers/net/wireless/b43/pcmcia.c index b242a9a90dd2..b79a6bd5396d 100644 --- a/drivers/net/wireless/b43/pcmcia.c +++ b/drivers/net/wireless/b43/pcmcia.c @@ -65,12 +65,12 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev) tuple_t tuple; cisparse_t parse; int err = -ENOMEM; - int res; + int res = 0; unsigned char buf[64]; ssb = kzalloc(sizeof(*ssb), GFP_KERNEL); if (!ssb) - goto out; + goto out_error; err = -ENODEV; tuple.DesiredTuple = CISTPL_CONFIG; @@ -96,10 +96,12 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev) dev->io.NumPorts2 = 0; dev->io.Attributes2 = 0; - win.Attributes = WIN_MEMORY_TYPE_CM | WIN_ENABLE | WIN_USE_WAIT; + win.Attributes = WIN_ADDR_SPACE_MEM | WIN_MEMORY_TYPE_CM | + WIN_ENABLE | WIN_DATA_WIDTH_16 | + WIN_USE_WAIT; win.Base = 0; win.Size = SSB_CORE_SIZE; - win.AccessSpeed = 1000; + win.AccessSpeed = 250; res = pcmcia_request_window(&dev, &win, &dev->win); if (res != CS_SUCCESS) goto err_kfree_ssb; @@ -108,21 +110,34 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev) mem.Page = 0; res = pcmcia_map_mem_page(dev->win, &mem); if (res != CS_SUCCESS) - goto err_kfree_ssb; + goto err_disable; + + dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_FIRST_SHARED; + dev->irq.IRQInfo1 = IRQ_LEVEL_ID | IRQ_SHARE_ID; + dev->irq.Handler = NULL; /* The handler is registered later. */ + dev->irq.Instance = NULL; + res = pcmcia_request_irq(dev, &dev->irq); + if (res != CS_SUCCESS) + goto err_disable; res = pcmcia_request_configuration(dev, &dev->conf); if (res != CS_SUCCESS) goto err_disable; err = ssb_bus_pcmciabus_register(ssb, dev, win.Base); + if (err) + goto err_disable; dev->priv = ssb; - out: - return err; - err_disable: + return 0; + +err_disable: pcmcia_disable_device(dev); - err_kfree_ssb: +err_kfree_ssb: kfree(ssb); +out_error: + printk(KERN_ERR "b43-pcmcia: Initialization failed (%d, %d)\n", + res, err); return err; } @@ -131,22 +146,21 @@ static void __devexit b43_pcmcia_remove(struct pcmcia_device *dev) struct ssb_bus *ssb = dev->priv; ssb_bus_unregister(ssb); - pcmcia_release_window(dev->win); pcmcia_disable_device(dev); kfree(ssb); dev->priv = NULL; } static struct pcmcia_driver b43_pcmcia_driver = { - .owner = THIS_MODULE, - .drv = { - .name = "b43-pcmcia", - }, - .id_table = b43_pcmcia_tbl, - .probe = b43_pcmcia_probe, - .remove = b43_pcmcia_remove, - .suspend = b43_pcmcia_suspend, - .resume = b43_pcmcia_resume, + .owner = THIS_MODULE, + .drv = { + .name = "b43-pcmcia", + }, + .id_table = b43_pcmcia_tbl, + .probe = b43_pcmcia_probe, + .remove = __devexit_p(b43_pcmcia_remove), + .suspend = b43_pcmcia_suspend, + .resume = b43_pcmcia_resume, }; int b43_pcmcia_init(void) diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c index 800e0a61a7f5..9b1f905ffbf4 100644 --- a/drivers/net/wireless/b43/rfkill.c +++ b/drivers/net/wireless/b43/rfkill.c @@ -47,32 +47,35 @@ static void b43_rfkill_poll(struct input_polled_dev *poll_dev) struct b43_wldev *dev = poll_dev->private; struct b43_wl *wl = dev->wl; bool enabled; + bool report_change = 0; mutex_lock(&wl->mutex); B43_WARN_ON(b43_status(dev) < B43_STAT_INITIALIZED); enabled = b43_is_hw_radio_enabled(dev); if (unlikely(enabled != dev->radio_hw_enable)) { dev->radio_hw_enable = enabled; + report_change = 1; b43info(wl, "Radio hardware status changed to %s\n", enabled ? "ENABLED" : "DISABLED"); - mutex_unlock(&wl->mutex); + } + mutex_unlock(&wl->mutex); + + if (unlikely(report_change)) input_report_key(poll_dev->input, KEY_WLAN, enabled); - } else - mutex_unlock(&wl->mutex); } -/* Called when the RFKILL toggled in software. - * This is called without locking. */ +/* Called when the RFKILL toggled in software. */ static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state) { struct b43_wldev *dev = data; struct b43_wl *wl = dev->wl; int err = 0; - mutex_lock(&wl->mutex); - if (b43_status(dev) < B43_STAT_INITIALIZED) - goto out_unlock; + if (!wl->rfkill.registered) + return 0; + mutex_lock(&wl->mutex); + B43_WARN_ON(b43_status(dev) < B43_STAT_INITIALIZED); switch (state) { case RFKILL_STATE_ON: if (!dev->radio_hw_enable) { @@ -89,7 +92,6 @@ static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state) b43_radio_turn_off(dev, 0); break; } - out_unlock: mutex_unlock(&wl->mutex); @@ -98,11 +100,11 @@ out_unlock: char * b43_rfkill_led_name(struct b43_wldev *dev) { - struct b43_wl *wl = dev->wl; + struct b43_rfkill *rfk = &(dev->wl->rfkill); - if (!wl->rfkill.rfkill) + if (!rfk->registered) return NULL; - return rfkill_get_led_name(wl->rfkill.rfkill); + return rfkill_get_led_name(rfk->rfkill); } void b43_rfkill_init(struct b43_wldev *dev) @@ -111,53 +113,13 @@ void b43_rfkill_init(struct b43_wldev *dev) struct b43_rfkill *rfk = &(wl->rfkill); int err; - if (rfk->rfkill) { - err = rfkill_register(rfk->rfkill); - if (err) { - b43warn(wl, "Failed to register RF-kill button\n"); - goto err_free_rfk; - } - } - if (rfk->poll_dev) { - err = input_register_polled_device(rfk->poll_dev); - if (err) { - b43warn(wl, "Failed to register RF-kill polldev\n"); - goto err_free_polldev; - } - } - - return; -err_free_rfk: - rfkill_free(rfk->rfkill); - rfk->rfkill = NULL; -err_free_polldev: - input_free_polled_device(rfk->poll_dev); - rfk->poll_dev = NULL; -} - -void b43_rfkill_exit(struct b43_wldev *dev) -{ - struct b43_rfkill *rfk = &(dev->wl->rfkill); - - if (rfk->poll_dev) - input_unregister_polled_device(rfk->poll_dev); - if (rfk->rfkill) - rfkill_unregister(rfk->rfkill); -} - -void b43_rfkill_alloc(struct b43_wldev *dev) -{ - struct b43_wl *wl = dev->wl; - struct b43_rfkill *rfk = &(wl->rfkill); + rfk->registered = 0; + rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN); + if (!rfk->rfkill) + goto out_error; snprintf(rfk->name, sizeof(rfk->name), "b43-%s", wiphy_name(wl->hw->wiphy)); - - rfk->rfkill = rfkill_allocate(dev->dev->dev, RFKILL_TYPE_WLAN); - if (!rfk->rfkill) { - b43warn(wl, "Failed to allocate RF-kill button\n"); - return; - } rfk->rfkill->name = rfk->name; rfk->rfkill->state = RFKILL_STATE_ON; rfk->rfkill->data = dev; @@ -165,18 +127,45 @@ void b43_rfkill_alloc(struct b43_wldev *dev) rfk->rfkill->user_claim_unsupported = 1; rfk->poll_dev = input_allocate_polled_device(); - if (rfk->poll_dev) { - rfk->poll_dev->private = dev; - rfk->poll_dev->poll = b43_rfkill_poll; - rfk->poll_dev->poll_interval = 1000; /* msecs */ - } else - b43warn(wl, "Failed to allocate RF-kill polldev\n"); + if (!rfk->poll_dev) + goto err_free_rfk; + rfk->poll_dev->private = dev; + rfk->poll_dev->poll = b43_rfkill_poll; + rfk->poll_dev->poll_interval = 1000; /* msecs */ + + err = rfkill_register(rfk->rfkill); + if (err) + goto err_free_polldev; + err = input_register_polled_device(rfk->poll_dev); + if (err) + goto err_unreg_rfk; + + rfk->registered = 1; + + return; +err_unreg_rfk: + rfkill_unregister(rfk->rfkill); +err_free_polldev: + input_free_polled_device(rfk->poll_dev); + rfk->poll_dev = NULL; +err_free_rfk: + rfkill_free(rfk->rfkill); + rfk->rfkill = NULL; +out_error: + rfk->registered = 0; + b43warn(wl, "RF-kill button init failed\n"); } -void b43_rfkill_free(struct b43_wldev *dev) +void b43_rfkill_exit(struct b43_wldev *dev) { struct b43_rfkill *rfk = &(dev->wl->rfkill); + if (!rfk->registered) + return; + rfk->registered = 0; + + input_unregister_polled_device(rfk->poll_dev); + rfkill_unregister(rfk->rfkill); input_free_polled_device(rfk->poll_dev); rfk->poll_dev = NULL; rfkill_free(rfk->rfkill); diff --git a/drivers/net/wireless/b43/rfkill.h b/drivers/net/wireless/b43/rfkill.h index 29544e8c9e5f..adacf936d815 100644 --- a/drivers/net/wireless/b43/rfkill.h +++ b/drivers/net/wireless/b43/rfkill.h @@ -15,14 +15,14 @@ struct b43_rfkill { struct rfkill *rfkill; /* The poll device for the RFKILL input button */ struct input_polled_dev *poll_dev; + /* Did initialization succeed? Used for freeing. */ + bool registered; /* The unique name of this rfkill switch */ - char name[32]; + char name[sizeof("b43-phy4294967295")]; }; -/* All the init functions return void, because we are not interested +/* The init function returns void, because we are not interested * in failing the b43 init process when rfkill init failed. */ -void b43_rfkill_alloc(struct b43_wldev *dev); -void b43_rfkill_free(struct b43_wldev *dev); void b43_rfkill_init(struct b43_wldev *dev); void b43_rfkill_exit(struct b43_wldev *dev); @@ -36,12 +36,6 @@ struct b43_rfkill { /* empty */ }; -static inline void b43_rfkill_alloc(struct b43_wldev *dev) -{ -} -static inline void b43_rfkill_free(struct b43_wldev *dev) -{ -} static inline void b43_rfkill_init(struct b43_wldev *dev) { } |