static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev) { struct hw_mode_spec *spec = &rt2x00dev->spec; int status; /* * Initialize HW modes. */ status = rt2x00lib_probe_hw_modes(rt2x00dev, spec); if (status) return status; /* * Initialize HW fields. */ rt2x00dev->hw->queues = rt2x00dev->ops->tx_queues; /* * Register HW. */ status = ieee80211_register_hw(rt2x00dev->hw); if (status) { rt2x00lib_remove_hw(rt2x00dev); return status; } __set_bit(DEVICE_REGISTERED_HW, &rt2x00dev->flags); return 0; }
void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) { clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); /* * Disable radio. */ rt2x00lib_disable_radio(rt2x00dev); /* * Stop all work. */ cancel_work_sync(&rt2x00dev->intf_work); cancel_work_sync(&rt2x00dev->rxdone_work); cancel_work_sync(&rt2x00dev->txdone_work); /* * Free the tx status fifo. */ kfifo_free(&rt2x00dev->txstatus_fifo); /* * Kill the tx status tasklet. */ tasklet_kill(&rt2x00dev->txstatus_tasklet); /* * Uninitialize device. */ rt2x00lib_uninitialize(rt2x00dev); /* * Free extra components */ rt2x00debug_deregister(rt2x00dev); rt2x00leds_unregister(rt2x00dev); /* * Free ieee80211_hw memory. */ rt2x00lib_remove_hw(rt2x00dev); /* * Free firmware image. */ rt2x00lib_free_firmware(rt2x00dev); /* * Free queue structures. */ rt2x00queue_free(rt2x00dev); }
void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) { __clear_bit(DEVICE_PRESENT, &rt2x00dev->flags); /* * Disable radio. */ rt2x00lib_disable_radio(rt2x00dev); /* * Uninitialize device. */ rt2x00lib_uninitialize(rt2x00dev); /* * Free extra components */ rt2x00debug_deregister(rt2x00dev); rt2x00rfkill_free(rt2x00dev); rt2x00leds_unregister(rt2x00dev); /* * Free ieee80211_hw memory. */ rt2x00lib_remove_hw(rt2x00dev); /* * Free firmware image. */ rt2x00lib_free_firmware(rt2x00dev); /* * Free queue structures. */ rt2x00queue_free(rt2x00dev); }
void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev) { clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); /* * Disable radio. */ rt2x00lib_disable_radio(rt2x00dev); /* * Stop all work. */ cancel_work_sync(&rt2x00dev->intf_work); cancel_delayed_work_sync(&rt2x00dev->autowakeup_work); cancel_work_sync(&rt2x00dev->sleep_work); if (rt2x00_is_usb(rt2x00dev)) { hrtimer_cancel(&rt2x00dev->txstatus_timer); cancel_work_sync(&rt2x00dev->rxdone_work); cancel_work_sync(&rt2x00dev->txdone_work); } if (rt2x00dev->workqueue) destroy_workqueue(rt2x00dev->workqueue); /* * Free the tx status fifo. */ kfifo_free(&rt2x00dev->txstatus_fifo); /* * Kill the tx status tasklet. */ tasklet_kill(&rt2x00dev->txstatus_tasklet); tasklet_kill(&rt2x00dev->pretbtt_tasklet); tasklet_kill(&rt2x00dev->tbtt_tasklet); tasklet_kill(&rt2x00dev->rxdone_tasklet); tasklet_kill(&rt2x00dev->autowake_tasklet); /* * Uninitialize device. */ rt2x00lib_uninitialize(rt2x00dev); /* * Free extra components */ rt2x00debug_deregister(rt2x00dev); rt2x00leds_unregister(rt2x00dev); /* * Free ieee80211_hw memory. */ rt2x00lib_remove_hw(rt2x00dev); /* * Free firmware image. */ rt2x00lib_free_firmware(rt2x00dev); /* * Free queue structures. */ rt2x00queue_free(rt2x00dev); /* * Free the driver data. */ if (rt2x00dev->drv_data) kfree(rt2x00dev->drv_data); }