It might be that the underlying infrastrucutre went away and the state is no longer valid. We ought to reinitialize it once a device appears again. This is the case when the nl80211 devices disappear and cfg8011 is remoed afterwards. The netlink handle is no longer valid (returns ENOENT) and a new one needs to be open if it's loaded back. Signed-off-by: Lubomir Rintel <lkundrak@xxxxx> --- wpa_supplicant/wpa_supplicant.c | 48 ++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 3f54547..efb9cd5 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -4665,6 +4665,28 @@ static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s, return 0; } +/* Deinitialize the driver if we're the last user. */ +static void wpa_drv_cleanup(struct wpa_supplicant *wpa_s) +{ + struct wpa_global *global = wpa_s->global; + struct wpa_supplicant *iface; + int i; + + if (!wpa_s->driver) + return; + + for (iface = global->ifaces; iface; iface = iface->next) + if (iface->driver == wpa_s->driver) + return; + + for (i = 0; wpa_drivers[i]; i++) + if (global->drv_priv[i] == wpa_s->global_drv_priv) + global->drv_priv[i] = NULL; + + if (wpa_s->driver->global_deinit) + wpa_s->driver->global_deinit (wpa_s->global_drv_priv); + wpa_s->global_drv_priv = NULL; +} static void wpa_supplicant_deinit_iface(struct wpa_supplicant *wpa_s, int notify, int terminate) @@ -4853,18 +4875,6 @@ int wpa_supplicant_remove_iface(struct wpa_global *global, char *ifname = NULL; #endif /* CONFIG_MESH */ - /* Remove interface from the global list of interfaces */ - prev = global->ifaces; - if (prev == wpa_s) { - global->ifaces = wpa_s->next; - } else { - while (prev && prev->next != wpa_s) - prev = prev->next; - if (prev == NULL) - return -1; - prev->next = wpa_s->next; - } - wpa_dbg(wpa_s, MSG_DEBUG, "Removing interface %s", wpa_s->ifname); #ifdef CONFIG_MESH @@ -4891,6 +4901,20 @@ int wpa_supplicant_remove_iface(struct wpa_global *global, } #endif /* CONFIG_MESH */ + /* Remove interface from the global list of interfaces */ + prev = global->ifaces; + if (prev == wpa_s) { + global->ifaces = wpa_s->next; + } else { + while (prev && prev->next != wpa_s) + prev = prev->next; + if (prev == NULL) + return -1; + prev->next = wpa_s->next; + } + + wpa_drv_cleanup(wpa_s); + return 0; } -- 2.4.3 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap