NetworkManager r4120 - in trunk: . src
- From: dcbw svn gnome org
- To: svn-commits-list gnome org
- Subject: NetworkManager r4120 - in trunk: . src
- Date: Mon, 29 Sep 2008 11:50:43 +0000 (UTC)
Author: dcbw
Date: Mon Sep 29 11:50:43 2008
New Revision: 4120
URL: http://svn.gnome.org/viewvc/NetworkManager?rev=4120&view=rev
Log:
2008-09-29 Dan Williams <dcbw redhat com>
Handle ipw3945 suspend/resume by retrying the GIWRANGE request a few times
when it returns EAGAIN (rh #362421)
* src/nm-device-wifi.c
- (wireless_get_range): try GIWRANGE a few times until the card responds
- (real_get_generic_capabilities, constructor): use wireless_get_range()
Modified:
trunk/ChangeLog
trunk/src/nm-device-wifi.c
Modified: trunk/src/nm-device-wifi.c
==============================================================================
--- trunk/src/nm-device-wifi.c (original)
+++ trunk/src/nm-device-wifi.c Mon Sep 29 11:50:43 2008
@@ -305,52 +305,98 @@
}
-static guint32
-real_get_generic_capabilities (NMDevice *dev)
+static gboolean
+wireless_get_range (NMDeviceWifi *self,
+ struct iw_range *range,
+ guint32 *response_len)
{
- int fd, err;
- guint32 caps = NM_DEVICE_CAP_NONE;
- struct iw_range range;
+ int fd, err, i = 26;
+ gboolean success = FALSE;
+ const char *iface;
struct iwreq wrq;
- const char *iface = nm_device_get_iface (dev);
- /* Check for Wireless Extensions support >= 16 for wireless devices */
+ g_return_val_if_fail (NM_IS_DEVICE_WIFI (self), FALSE);
+ g_return_val_if_fail (range != NULL, FALSE);
+
+ iface = nm_device_get_iface (NM_DEVICE (self));
fd = socket (PF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
- nm_warning ("couldn't open control socket.");
- goto out;
+ nm_warning ("(%s): couldn't open control socket.", iface);
+ return FALSE;
}
memset (&wrq, 0, sizeof (struct iwreq));
- memset (&range, 0, sizeof (struct iw_range));
strncpy (wrq.ifr_name, iface, IFNAMSIZ);
- wrq.u.data.pointer = (caddr_t) ⦥
+ wrq.u.data.pointer = (caddr_t) range;
wrq.u.data.length = sizeof (struct iw_range);
- if (ioctl (fd, SIOCGIWRANGE, &wrq) < 0) {
- nm_warning ("couldn't get driver range information.");
- goto out;
+ /* Need to give some drivers time to recover after suspend/resume
+ * (ex ipw3945 takes a few seconds to talk to its regulatory daemon;
+ * see rh bz#362421)
+ */
+ while (i-- > 0) {
+ err = ioctl (fd, SIOCGIWRANGE, &wrq);
+ if (err == 0) {
+ if (response_len)
+ *response_len = wrq.u.data.length;
+ success = TRUE;
+ break;
+ } else if (errno != EAGAIN) {
+ nm_warning ("(%s): couldn't get driver range information (%d).", iface, errno);
+ break;
+ }
+
+ g_usleep (G_USEC_PER_SEC / 4);
}
- if ((wrq.u.data.length < 300) || (range.we_version_compiled < 16)) {
- nm_warning ("%s: driver's Wireless Extensions version (%d) is too old.",
+ if (i <= 0)
+ nm_warning ("(%s): driver took too long to responde to IWRANGE query.", iface);
+
+ close (fd);
+ return success;
+}
+
+static guint32
+real_get_generic_capabilities (NMDevice *dev)
+{
+ int fd, err;
+ guint32 caps = NM_DEVICE_CAP_NONE, response_len = 0;
+ struct iwreq wrq;
+ struct iw_range range;
+ const char *iface = nm_device_get_iface (dev);
+ gboolean success;
+
+ memset (&range, 0, sizeof (struct iw_range));
+ success = wireless_get_range (NM_DEVICE_WIFI (dev), &range, &response_len);
+ if (!success)
+ return NM_DEVICE_CAP_NONE;
+
+ /* Check for Wireless Extensions support >= 16 for wireless devices */
+ if ((response_len < 300) || (range.we_version_compiled < 16)) {
+ nm_warning ("(%s): driver's Wireless Extensions version (%d) is too old.",
iface, range.we_version_compiled);
+ return NM_DEVICE_CAP_NONE;
+ }
+
+ fd = socket (PF_INET, SOCK_DGRAM, 0);
+ if (fd < 0) {
+ nm_warning ("(%s): couldn't open control socket.", iface);
goto out;
- } else {
- caps |= NM_DEVICE_CAP_NM_SUPPORTED;
}
- /* Card's that don't scan aren't supported */
+ /* Cards that don't scan aren't supported */
memset (&wrq, 0, sizeof (struct iwreq));
strncpy (wrq.ifr_name, iface, IFNAMSIZ);
err = ioctl (fd, SIOCSIWSCAN, &wrq);
+ close (fd);
+
if ((err == -1) && (errno == EOPNOTSUPP))
caps = NM_DEVICE_CAP_NONE;
+ else
+ caps |= NM_DEVICE_CAP_NM_SUPPORTED;
out:
- if (fd >= 0)
- close (fd);
return caps;
}
@@ -472,11 +518,11 @@
GObjectClass *klass;
NMDeviceWifi *self;
NMDeviceWifiPrivate *priv;
- const char *iface;
- int fd, i, err;
struct iw_range range;
struct iw_range_with_scan_capa *scan_capa_range;
struct iwreq wrq;
+ gboolean success;
+ int i;
klass = G_OBJECT_CLASS (nm_device_wifi_parent_class);
object = klass->constructor (type, n_construct_params, construct_params);
@@ -486,20 +532,9 @@
self = NM_DEVICE_WIFI (object);
priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
- iface = nm_device_get_iface (NM_DEVICE (self));
- fd = socket (PF_INET, SOCK_DGRAM, 0);
- if (fd < 0)
- goto error;
-
- memset (&wrq, 0, sizeof (struct iwreq));
memset (&range, 0, sizeof (struct iw_range));
- strncpy (wrq.ifr_name, iface, IFNAMSIZ);
- wrq.u.data.pointer = (caddr_t) ⦥
- wrq.u.data.length = sizeof (struct iw_range);
-
- err = ioctl (fd, SIOCGIWRANGE, &wrq);
- close (fd);
- if (err < 0)
+ success = wireless_get_range (NM_DEVICE_WIFI (object), &range, NULL);
+ if (!success)
goto error;
priv->max_qual.qual = range.max_qual.qual;
@@ -3364,6 +3399,12 @@
* the device is now ready to use.
*/
if (priv->enabled) {
+ gboolean success;
+ struct iw_range range;
+
+ /* Wait for some drivers like ipw3945 to come back to life */
+ success = wireless_get_range (self, &range, NULL);
+
if (!priv->supplicant.iface)
supplicant_interface_acquire (self);
@@ -3466,7 +3507,8 @@
return;
if (enabled) {
- gboolean no_firmware = FALSE;
+ gboolean no_firmware = FALSE, success;
+ struct iw_range range;
if (state != NM_DEVICE_STATE_UNAVAILABLE);
nm_warning ("not in expected unavailable state!");
@@ -3477,6 +3519,9 @@
return;
}
+ /* Wait for some drivers like ipw3945 to come back to life */
+ success = wireless_get_range (self, &range, NULL);
+
if (!priv->supplicant.iface)
supplicant_interface_acquire (self);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]