2008-08-18 Dan Williams <dcbw@redhat.com>
authorDan Williams <dcbw@redhat.com>
Mon, 18 Aug 2008 18:29:47 +0000 (18:29 +0000)
committerDan Williams <dcbw@redhat.com>
Mon, 18 Aug 2008 18:29:47 +0000 (18:29 +0000)
* include/NetworkManager.h
  introspection/nm-device.xml
- Add a "missing firmware" device state reason

* src/NetworkManagerSystem.c
  src/NetworkManagerSystem.h
- (nm_system_device_set_up_down): add a no_firmware argument
- (nm_system_device_set_up_down_with_iface): if the result of setting
IFF_UP is ENOENT, that almost always means missing firmware

* src/backends/NetworkManagerGeneric.c
  src/nm-device-ethernet.c
  src/nm-device-private.h
  src/nm-device-wifi.c
  src/nm-device.c
  src/nm-device.h
  src/nm-hso-gsm-device.c
  src/vpn-manager/nm-vpn-connection.c
- Pass no_firmware along; check it where appropriate

git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3983 4912f4e0-d625-0410-9fb7-b9a5a253dbdc

13 files changed:
ChangeLog
include/NetworkManager.h
introspection/nm-device.xml
src/NetworkManagerSystem.c
src/NetworkManagerSystem.h
src/backends/NetworkManagerGeneric.c
src/nm-device-ethernet.c
src/nm-device-private.h
src/nm-device-wifi.c
src/nm-device.c
src/nm-device.h
src/nm-hso-gsm-device.c
src/vpn-manager/nm-vpn-connection.c

index e03adf4..3f86c36 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,27 @@
 2008-08-18  Dan Williams  <dcbw@redhat.com>
 
+       * include/NetworkManager.h
+         introspection/nm-device.xml
+               - Add a "missing firmware" device state reason
+
+       * src/NetworkManagerSystem.c
+         src/NetworkManagerSystem.h
+               - (nm_system_device_set_up_down): add a no_firmware argument
+               - (nm_system_device_set_up_down_with_iface): if the result of setting
+                       IFF_UP is ENOENT, that almost always means missing firmware
+
+       * src/backends/NetworkManagerGeneric.c
+         src/nm-device-ethernet.c
+         src/nm-device-private.h
+         src/nm-device-wifi.c
+         src/nm-device.c
+         src/nm-device.h
+         src/nm-hso-gsm-device.c
+         src/vpn-manager/nm-vpn-connection.c
+               - Pass no_firmware along; check it where appropriate
+
+2008-08-18  Dan Williams  <dcbw@redhat.com>
+
        Patch from Robert Buchholz <rbu@gentoo.org>
 
        * autogen.sh
index 825c22a..39358ed 100644 (file)
@@ -322,6 +322,9 @@ typedef enum {
        /* PIN check failed */
        NM_DEVICE_STATE_REASON_GSM_PIN_CHECK_FAILED,
 
+       /* Necessary firmware for the device may be missing */
+       NM_DEVICE_STATE_REASON_FIRMWARE_MISSING,
+
        /* Unused */
        NM_DEVICE_STATE_REASON_LAST = 0xFFFF
 } NMDeviceStateReason;
index 22b636c..c5d785e 100644 (file)
           PIN check failed.
         </tp:docstring>
       </tp:enumvalue>
+      <tp:enumvalue suffix="FIRMWARE_MISSING" value="35">
+        <tp:docstring>
+          Necessary firmware for the device may be missing.
+        </tp:docstring>
+      </tp:enumvalue>
        </tp:enum>
 
   </interface>
index c97d18d..c736507 100644 (file)
@@ -358,7 +358,7 @@ nm_system_vpn_device_set_from_ip4_config (NMDevice *active_device,
        if (!iface || !strlen (iface))
                goto out;
 
-       nm_system_device_set_up_down_with_iface (iface, TRUE);
+       nm_system_device_set_up_down_with_iface (iface, TRUE, NULL);
 
        if (!add_ip4_addresses (config, iface))
                goto out;
@@ -419,14 +419,20 @@ gboolean nm_system_vpn_device_unset_from_ip4_config (NMDevice *active_device, co
  * Mark the device as up or down.
  *
  */
-gboolean nm_system_device_set_up_down (NMDevice *dev, gboolean up)
+gboolean
+nm_system_device_set_up_down (NMDevice *dev,
+                              gboolean up,
+                              gboolean *no_firmware)
 {
        g_return_val_if_fail (dev != NULL, FALSE);
 
-       return nm_system_device_set_up_down_with_iface (nm_device_get_iface (dev), up);
+       return nm_system_device_set_up_down_with_iface (nm_device_get_iface (dev), up, no_firmware);
 }
 
-gboolean nm_system_device_set_up_down_with_iface (const char *iface, gboolean up)
+gboolean
+nm_system_device_set_up_down_with_iface (const char *iface,
+                                         gboolean up,
+                                         gboolean *no_firmware)
 {
        struct rtnl_link *request = NULL, *old = NULL;
        struct nl_handle *nlh;
@@ -434,6 +440,8 @@ gboolean nm_system_device_set_up_down_with_iface (const char *iface, gboolean up
        guint32 idx;
 
        g_return_val_if_fail (iface != NULL, FALSE);
+       if (no_firmware)
+               g_return_val_if_fail (*no_firmware == FALSE, FALSE);
 
        if (!(request = rtnl_link_alloc ()))
                goto out;
@@ -447,8 +455,12 @@ gboolean nm_system_device_set_up_down_with_iface (const char *iface, gboolean up
        old = nm_netlink_index_to_rtnl_link (idx);
        if (old) {
                nlh = nm_netlink_get_default_handle ();
-               if (nlh)
-                       success = (rtnl_link_change (nlh, old, request, 0) == 0) ? TRUE : FALSE;
+               if (nlh) {
+                       if (rtnl_link_change (nlh, old, request, 0) == 0)
+                               success = TRUE;
+                       else if ((nl_get_errno () == ENOENT) && no_firmware && up)
+                               *no_firmware = TRUE;
+               }
        }
 
        rtnl_link_put (old);
index 60e24c6..eb321df 100644 (file)
@@ -56,8 +56,12 @@ gboolean             nm_system_vpn_device_unset_from_ip4_config      (NMDevice *active_device,
                                                                         const char *iface,
                                                                         NMIP4Config *config);
 
-gboolean               nm_system_device_set_up_down                            (NMDevice *dev, gboolean up);
-gboolean               nm_system_device_set_up_down_with_iface         (const char *iface, gboolean up);
+gboolean               nm_system_device_set_up_down                            (NMDevice *dev,
+                                                             gboolean up,
+                                                             gboolean *no_firmware);
+gboolean               nm_system_device_set_up_down_with_iface         (const char *iface,
+                                                             gboolean up,
+                                                             gboolean *no_firmware);
 
 gboolean        nm_system_device_is_up (NMDevice *device);
 gboolean        nm_system_device_is_up_with_iface (const char *iface);
index 93b1e12..1cf0021 100644 (file)
@@ -58,7 +58,7 @@ void nm_generic_enable_loopback (void)
        int                     iface_idx = -1;
        int                     err;
 
-       nm_system_device_set_up_down_with_iface ("lo", TRUE);
+       nm_system_device_set_up_down_with_iface ("lo", TRUE, NULL);
 
        nlh = nm_netlink_get_default_handle ();
        if (!nlh)
index 7db4063..b00ce2c 100644 (file)
@@ -357,15 +357,15 @@ real_hw_is_up (NMDevice *device)
 }
 
 static gboolean
-real_hw_bring_up (NMDevice *dev)
+real_hw_bring_up (NMDevice *dev, gboolean *no_firmware)
 {
-       return nm_system_device_set_up_down (dev, TRUE);
+       return nm_system_device_set_up_down (dev, TRUE, no_firmware);
 }
 
 static void
 real_hw_take_down (NMDevice *dev)
 {
-       nm_system_device_set_up_down (dev, FALSE);
+       nm_system_device_set_up_down (dev, FALSE, NULL);
 }
 
 NMDeviceEthernet *
index 698f273..97c8bff 100644 (file)
@@ -34,9 +34,9 @@ void nm_device_state_changed (NMDevice *device,
                               NMDeviceState state,
                               NMDeviceStateReason reason);
 
-gboolean nm_device_hw_bring_up (NMDevice *self, gboolean wait);
+gboolean nm_device_hw_bring_up (NMDevice *self, gboolean wait, gboolean *no_firmware);
 
-void nm_device_hw_take_down (NMDevice *self, gboolean wait);
+void nm_device_hw_take_down (NMDevice *self, gboolean block);
 
 void nm_device_handle_autoip4_event (NMDevice *self,
                                      const char *event,
index 744c3b0..4011475 100644 (file)
@@ -797,15 +797,15 @@ real_hw_is_up (NMDevice *device)
 }
 
 static gboolean
-real_hw_bring_up (NMDevice *dev)
+real_hw_bring_up (NMDevice *dev, gboolean *no_firmware)
 {
-       return nm_system_device_set_up_down (dev, TRUE);
+       return nm_system_device_set_up_down (dev, TRUE, no_firmware);
 }
 
 static void
 real_hw_take_down (NMDevice *dev)
 {
-       nm_system_device_set_up_down (dev, FALSE);
+       nm_system_device_set_up_down (dev, FALSE, NULL);
 }
 
 static gboolean
@@ -3416,10 +3416,12 @@ nm_device_wifi_set_enabled (NMDeviceWifi *self, gboolean enabled)
                return;
 
        if (enabled) {
+               gboolean no_firmware = FALSE;
+
                if (state != NM_DEVICE_STATE_UNAVAILABLE);
                        nm_warning ("not in expected unavailable state!");
 
-               if (!nm_device_hw_bring_up (NM_DEVICE (self), TRUE)) {
+               if (!nm_device_hw_bring_up (NM_DEVICE (self), TRUE, &no_firmware)) {
                        /* The device sucks, or HAL was lying to us about the killswitch state */
                        priv->enabled = FALSE;
                        return;
index 37cb500..6628bc3 100644 (file)
@@ -116,7 +116,7 @@ static gboolean nm_device_activate (NMDeviceInterface *device,
 static void    nm_device_activate_schedule_stage5_ip_config_commit (NMDevice *self);
 static void nm_device_deactivate (NMDeviceInterface *device);
 
-static gboolean nm_device_bring_up (NMDevice *self, gboolean wait);
+static gboolean nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware);
 static gboolean nm_device_is_up (NMDevice *self);
 
 static void
@@ -480,6 +480,7 @@ nm_device_activate_stage2_device_config (gpointer user_data)
        const char *     iface;
        NMActStageReturn ret;
        NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
+       gboolean no_firmware = FALSE;
 
        /* Clear the activation source ID now that this stage has run */
        if (self->priv->act_source_id > 0)
@@ -489,8 +490,11 @@ nm_device_activate_stage2_device_config (gpointer user_data)
        nm_info ("Activation (%s) Stage 2 of 5 (Device Configure) starting...", iface);
        nm_device_state_changed (self, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_REASON_NONE);
 
-       if (!nm_device_bring_up (self, FALSE)) {
-               nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_CONFIG_FAILED);
+       if (!nm_device_bring_up (self, FALSE, &no_firmware)) {
+               if (no_firmware)
+                       nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_FIRMWARE_MISSING);
+               else
+                       nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_CONFIG_FAILED);
                goto out;
        }
 
@@ -1044,7 +1048,7 @@ real_act_stage4_get_ip4_config (NMDevice *self,
 
        if (!*config) {
                /* Make sure device is up even if config fails */
-               nm_device_bring_up (self, FALSE);
+               nm_device_bring_up (self, FALSE, NULL);
        } else
                ret = NM_ACT_STAGE_RETURN_SUCCESS;
 
@@ -1946,7 +1950,7 @@ nm_device_is_up (NMDevice *self)
 }
 
 gboolean
-nm_device_hw_bring_up (NMDevice *self, gboolean do_wait)
+nm_device_hw_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware)
 {
        gboolean success;
        guint32 tries = 0;
@@ -1959,13 +1963,13 @@ nm_device_hw_bring_up (NMDevice *self, gboolean do_wait)
        nm_info ("(%s): bringing up device.", nm_device_get_iface (self));
 
        if (NM_DEVICE_GET_CLASS (self)->hw_bring_up) {
-               success = NM_DEVICE_GET_CLASS (self)->hw_bring_up (self);
+               success = NM_DEVICE_GET_CLASS (self)->hw_bring_up (self, no_firmware);
                if (!success)
                        return FALSE;
        }
 
        /* Wait for the device to come up if requested */
-       while (do_wait && !nm_device_hw_is_up (self) && (tries++ < 50))
+       while (block && !nm_device_hw_is_up (self) && (tries++ < 50))
                g_usleep (200);
 
        if (!nm_device_hw_is_up (self)) {
@@ -1983,7 +1987,7 @@ out:
 }
 
 void
-nm_device_hw_take_down (NMDevice *self, gboolean do_wait)
+nm_device_hw_take_down (NMDevice *self, gboolean block)
 {
        guint32 tries = 0;
 
@@ -1998,18 +2002,18 @@ nm_device_hw_take_down (NMDevice *self, gboolean do_wait)
                NM_DEVICE_GET_CLASS (self)->hw_take_down (self);
 
        /* Wait for the device to come up if requested */
-       while (do_wait && nm_device_hw_is_up (self) && (tries++ < 50))
+       while (block && nm_device_hw_is_up (self) && (tries++ < 50))
                g_usleep (200);
 }
 
 static gboolean
-nm_device_bring_up (NMDevice *self, gboolean do_wait)
+nm_device_bring_up (NMDevice *self, gboolean block, gboolean *no_firmware)
 {
-       gboolean success;
+       gboolean success = FALSE;
 
        g_return_val_if_fail (NM_IS_DEVICE (self), FALSE);
 
-       if (!nm_device_hw_bring_up (self, do_wait))
+       if (!nm_device_hw_bring_up (self, block, no_firmware))
                return FALSE;
 
        if (nm_device_is_up (self))
@@ -2017,17 +2021,14 @@ nm_device_bring_up (NMDevice *self, gboolean do_wait)
 
        nm_info ("(%s): preparing device.", nm_device_get_iface (self));
 
-       if (NM_DEVICE_GET_CLASS (self)->bring_up) {
+       if (NM_DEVICE_GET_CLASS (self)->bring_up)
                success = NM_DEVICE_GET_CLASS (self)->bring_up (self);
-               if (!success)
-                       return FALSE;
-       }
 
-       return TRUE;
+       return success;
 }
 
 void
-nm_device_take_down (NMDevice *self, gboolean do_wait)
+nm_device_take_down (NMDevice *self, gboolean block)
 {
        g_return_if_fail (NM_IS_DEVICE (self));
 
@@ -2041,7 +2042,7 @@ nm_device_take_down (NMDevice *self, gboolean do_wait)
                        NM_DEVICE_GET_CLASS (self)->take_down (self);
        }
 
-       nm_device_hw_take_down (self, do_wait);
+       nm_device_hw_take_down (self, block);
 }
 
 static void
@@ -2287,6 +2288,7 @@ nm_device_state_changed (NMDevice *device,
        NMDevicePrivate *priv;
        NMDeviceState old_state;
        NMActRequest *req;
+       gboolean no_firmware = FALSE;
 
        g_return_if_fail (NM_IS_DEVICE (device));
        priv = device->priv;
@@ -2315,8 +2317,10 @@ nm_info ("(%s): device state change: %d -> %d", nm_device_get_iface (device), ol
                        nm_device_take_down (device, TRUE);
                break;
        case NM_DEVICE_STATE_UNAVAILABLE:
-               if (old_state == NM_DEVICE_STATE_UNMANAGED)
-                       nm_device_bring_up (device, TRUE);
+               if (old_state == NM_DEVICE_STATE_UNMANAGED) {
+                       if (!nm_device_bring_up (device, TRUE, &no_firmware) && no_firmware)
+                               nm_warning ("%s: firmware may be missing.", nm_device_get_iface (device));
+               }
                /* Fall through, so when the device needs to be deactivated due to
                 * eg carrier changes we actually deactivate it */
        case NM_DEVICE_STATE_DISCONNECTED:
index 6a04d59..9412a8f 100644 (file)
@@ -66,7 +66,7 @@ struct _NMDeviceClass
 
        /* Hardware state, ie IFF_UP */
        gboolean        (*hw_is_up)      (NMDevice *self);
-       gboolean        (*hw_bring_up)   (NMDevice *self);
+       gboolean        (*hw_bring_up)   (NMDevice *self, gboolean *no_firmware);
        void            (*hw_take_down)  (NMDevice *self);
 
        /* Additional stuff required to operate the device, like a 
index d659dcb..009d803 100644 (file)
@@ -361,13 +361,19 @@ real_act_stage4_get_ip4_config (NMDevice *device,
 {
        NMHsoGsmDevice *self = NM_HSO_GSM_DEVICE (device);
        NMHsoGsmDevicePrivate *priv = NM_HSO_GSM_DEVICE_GET_PRIVATE (self);
+       gboolean no_firmware = FALSE;
 
        g_return_val_if_fail (config != NULL, NM_ACT_STAGE_RETURN_FAILURE);
        g_return_val_if_fail (*config == NULL, NM_ACT_STAGE_RETURN_FAILURE);
 
        nm_device_set_ip_iface (device, priv->netdev_iface);
-       if (!nm_device_hw_bring_up (device, TRUE))
+       if (!nm_device_hw_bring_up (device, TRUE, &no_firmware)) {
+               if (no_firmware)
+                       *reason = NM_DEVICE_STATE_REASON_FIRMWARE_MISSING;
+               else
+                       *reason = NM_DEVICE_STATE_REASON_CONFIG_FAILED;
                return NM_ACT_STAGE_RETURN_FAILURE;
+       }
 
        *config = priv->pending_ip4_config;
        priv->pending_ip4_config = NULL;
@@ -428,7 +434,7 @@ real_deactivate (NMDevice *device)
        if (priv->netdev_iface) {
                nm_system_device_flush_ip4_routes_with_iface (priv->netdev_iface);
                nm_system_device_flush_ip4_addresses_with_iface (priv->netdev_iface);
-               nm_system_device_set_up_down_with_iface (priv->netdev_iface, FALSE);
+               nm_system_device_set_up_down_with_iface (priv->netdev_iface, FALSE, NULL);
        }
        nm_device_set_ip_iface (device, NULL);
 
@@ -453,7 +459,7 @@ real_hw_is_up (NMDevice *device)
 }
 
 static gboolean
-real_hw_bring_up (NMDevice *device)
+real_hw_bring_up (NMDevice *device, gboolean *no_firmware)
 {
        NMHsoGsmDevicePrivate *priv = NM_HSO_GSM_DEVICE_GET_PRIVATE (device);
        NMDeviceState state;
@@ -463,7 +469,7 @@ real_hw_bring_up (NMDevice *device)
        if (   priv->pending_ip4_config
            || (state == NM_DEVICE_STATE_IP_CONFIG)
            || (state == NM_DEVICE_STATE_ACTIVATED))
-               return nm_system_device_set_up_down_with_iface (priv->netdev_iface, TRUE);
+               return nm_system_device_set_up_down_with_iface (priv->netdev_iface, TRUE, no_firmware);
 
        return TRUE;
 }
index 94424e9..b073e97 100644 (file)
@@ -829,7 +829,7 @@ connection_state_changed (NMVPNConnection *connection,
                }
 
                if (priv->tundev) {
-                       nm_system_device_set_up_down_with_iface (priv->tundev, FALSE);
+                       nm_system_device_set_up_down_with_iface (priv->tundev, FALSE, NULL);
                        nm_system_device_flush_ip4_routes_with_iface (priv->tundev);
                        nm_system_device_flush_ip4_addresses_with_iface (priv->tundev);
                }