/* * driver allocation handlers. */ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) { int retval = -ENOMEM; /* * Make room for rt2x00_intf inside the per-interface * structure ieee80211_vif. */ rt2x00dev->hw->vif_data_size = sizeof(struct rt2x00_intf); /* * Let the driver probe the device to detect the capabilities. */ retval = rt2x00dev->ops->lib->probe_hw(rt2x00dev); if (retval) { ERROR(rt2x00dev, "Failed to allocate device.\n"); goto exit; } /* * Initialize configuration work. */ INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); INIT_WORK(&rt2x00dev->filter_work, rt2x00lib_packetfilter_scheduled); INIT_DELAYED_WORK(&rt2x00dev->link.work, rt2x00lib_link_tuner); /* * Allocate queue array. */ retval = rt2x00queue_allocate(rt2x00dev); if (retval) goto exit; /* * Initialize ieee80211 structure. */ retval = rt2x00lib_probe_hw(rt2x00dev); if (retval) { ERROR(rt2x00dev, "Failed to initialize hw.\n"); goto exit; } /* * Register extra components. */ rt2x00leds_register(rt2x00dev); rt2x00rfkill_allocate(rt2x00dev); rt2x00debug_register(rt2x00dev); __set_bit(DEVICE_PRESENT, &rt2x00dev->flags); return 0; exit: rt2x00lib_remove_dev(rt2x00dev); return retval; }
int rt2x00soc_remove(struct platform_device *pdev) { struct ieee80211_hw *hw = platform_get_drvdata(pdev); struct rt2x00_dev *rt2x00dev = hw->priv; /* * Free all allocated data. */ rt2x00lib_remove_dev(rt2x00dev); rt2x00soc_free_reg(rt2x00dev); ieee80211_free_hw(hw); return 0; }
void rt2x00pci_remove(struct pci_dev *pci_dev) { struct ieee80211_hw *hw = pci_get_drvdata(pci_dev); struct rt2x00_dev *rt2x00dev = hw->priv; /* * Free all allocated data. */ rt2x00lib_remove_dev(rt2x00dev); rt2x00pci_free_reg(rt2x00dev); ieee80211_free_hw(hw); /* * Free the PCI device data. */ pci_clear_mwi(pci_dev); pci_disable_device(pci_dev); pci_release_regions(pci_dev); }
/* * driver allocation handlers. */ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) { int retval = -ENOMEM; /* * Allocate the driver data memory, if necessary. */ if (rt2x00dev->ops->drv_data_size > 0) { rt2x00dev->drv_data = kzalloc(rt2x00dev->ops->drv_data_size, GFP_KERNEL); if (!rt2x00dev->drv_data) { retval = -ENOMEM; goto exit; } } spin_lock_init(&rt2x00dev->irqmask_lock); mutex_init(&rt2x00dev->csr_mutex); set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); /* * Make room for rt2x00_intf inside the per-interface * structure ieee80211_vif. */ rt2x00dev->hw->vif_data_size = sizeof(struct rt2x00_intf); /* * Determine which operating modes are supported, all modes * which require beaconing, depend on the availability of * beacon entries. */ rt2x00dev->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); if (rt2x00dev->ops->bcn->entry_num > 0) rt2x00dev->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MESH_POINT) | BIT(NL80211_IFTYPE_WDS); /* * Initialize work. */ rt2x00dev->workqueue = alloc_ordered_workqueue(wiphy_name(rt2x00dev->hw->wiphy), 0); if (!rt2x00dev->workqueue) { retval = -ENOMEM; goto exit; } INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup); INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep); /* * Let the driver probe the device to detect the capabilities. */ retval = rt2x00dev->ops->lib->probe_hw(rt2x00dev); if (retval) { ERROR(rt2x00dev, "Failed to allocate device.\n"); goto exit; } /* * Allocate queue array. */ retval = rt2x00queue_allocate(rt2x00dev); if (retval) goto exit; /* * Initialize ieee80211 structure. */ retval = rt2x00lib_probe_hw(rt2x00dev); if (retval) { ERROR(rt2x00dev, "Failed to initialize hw.\n"); goto exit; } /* * Register extra components. */ rt2x00link_register(rt2x00dev); rt2x00leds_register(rt2x00dev); rt2x00debug_register(rt2x00dev); return 0; exit: rt2x00lib_remove_dev(rt2x00dev); return retval; }
/* * driver allocation handlers. */ int rt2x00lib_probe_dev(struct rt2x00_dev *rt2x00dev) { int retval = -ENOMEM; mutex_init(&rt2x00dev->csr_mutex); set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); /* * Make room for rt2x00_intf inside the per-interface * structure ieee80211_vif. */ rt2x00dev->hw->vif_data_size = sizeof(struct rt2x00_intf); /* * Determine which operating modes are supported, all modes * which require beaconing, depend on the availability of * beacon entries. */ rt2x00dev->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); if (rt2x00dev->ops->bcn->entry_num > 0) rt2x00dev->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP) | BIT(NL80211_IFTYPE_MESH_POINT) | BIT(NL80211_IFTYPE_WDS); /* * Let the driver probe the device to detect the capabilities. */ retval = rt2x00dev->ops->lib->probe_hw(rt2x00dev); if (retval) { ERROR(rt2x00dev, "Failed to allocate device.\n"); goto exit; } /* * Initialize configuration work. */ INIT_WORK(&rt2x00dev->intf_work, rt2x00lib_intf_scheduled); /* * Allocate queue array. */ retval = rt2x00queue_allocate(rt2x00dev); if (retval) goto exit; /* * Initialize ieee80211 structure. */ retval = rt2x00lib_probe_hw(rt2x00dev); if (retval) { ERROR(rt2x00dev, "Failed to initialize hw.\n"); goto exit; } /* * Register extra components. */ rt2x00link_register(rt2x00dev); rt2x00leds_register(rt2x00dev); rt2x00debug_register(rt2x00dev); return 0; exit: rt2x00lib_remove_dev(rt2x00dev); return retval; }