void lbs_remove_card(struct lbs_private *priv) { struct net_device *dev = priv->dev; lbs_remove_mesh(priv); if (priv->wiphy_registered) lbs_scan_deinit(priv); lbs_wait_for_firmware_load(priv); /* worker thread destruction blocks on the in-flight command which * should have been cleared already in lbs_stop_card(). */ lbs_deb_main("destroying worker thread\n"); destroy_workqueue(priv->work_thread); lbs_deb_main("done destroying worker thread\n"); if (priv->psmode == LBS802_11POWERMODEMAX_PSP) { priv->psmode = LBS802_11POWERMODECAM; /* no need to wakeup if already woken up, * on suspend, this exit ps command is not processed * the driver hangs */ if (priv->psstate != PS_STATE_FULL_POWER) lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, true); } if (priv->is_deep_sleep) { priv->is_deep_sleep = 0; wake_up_interruptible(&priv->ds_awake_q); } priv->is_host_sleep_configured = 0; priv->is_host_sleep_activated = 0; wake_up_interruptible(&priv->host_sleep_q); /* Stop the thread servicing the interrupts */ priv->surpriseremoved = 1; kthread_stop(priv->main_thread); lbs_free_adapter(priv); lbs_cfg_free(priv); free_netdev(dev); }
/** * lbs_mesh_set - Set function for sysfs attribute mesh * @dev: the &struct device * @attr: device attributes * @buf: buffer that contains new attribute value * @count: size of buffer */ static ssize_t lbs_mesh_set(struct device *dev, struct device_attribute *attr, const char * buf, size_t count) { struct lbs_private *priv = to_net_dev(dev)->ml_priv; int enable; sscanf(buf, "%x", &enable); enable = !!enable; if (enable == !!priv->mesh_dev) return count; if (enable) lbs_add_mesh(priv); else lbs_remove_mesh(priv); return count; }
void lbs_remove_card(struct lbs_private *priv) { struct net_device *dev = priv->dev; lbs_deb_enter(LBS_DEB_MAIN); lbs_remove_mesh(priv); lbs_scan_deinit(priv); /* worker thread destruction blocks on the in-flight command which * should have been cleared already in lbs_stop_card(). */ lbs_deb_main("destroying worker thread\n"); destroy_workqueue(priv->work_thread); lbs_deb_main("done destroying worker thread\n"); if (priv->psmode == LBS802_11POWERMODEMAX_PSP) { priv->psmode = LBS802_11POWERMODECAM; lbs_set_ps_mode(priv, PS_MODE_ACTION_EXIT_PS, true); } if (priv->is_deep_sleep) { priv->is_deep_sleep = 0; wake_up_interruptible(&priv->ds_awake_q); } priv->is_host_sleep_configured = 0; priv->is_host_sleep_activated = 0; wake_up_interruptible(&priv->host_sleep_q); /* Stop the thread servicing the interrupts */ priv->surpriseremoved = 1; kthread_stop(priv->main_thread); lbs_free_adapter(priv); lbs_cfg_free(priv); free_netdev(dev); lbs_deb_leave(LBS_DEB_MAIN); }
/** * Set function for sysfs attribute mesh */ static ssize_t lbs_mesh_set(struct device *dev, struct device_attribute *attr, const char * buf, size_t count) { struct lbs_private *priv = to_net_dev(dev)->ml_priv; int enable; int ret, action = CMD_ACT_MESH_CONFIG_STOP; sscanf(buf, "%x", &enable); enable = !!enable; if (enable == !!priv->mesh_dev) return count; if (enable) action = CMD_ACT_MESH_CONFIG_START; ret = lbs_mesh_config(priv, action, priv->channel); if (ret) return ret; if (enable) lbs_add_mesh(priv); else lbs_remove_mesh(priv); return count; }