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



git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3983 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams 2008-08-18 18:29:47 +00:00
parent 725a9825a7
commit 728dccd92c
13 changed files with 103 additions and 45 deletions

View file

@ -1,3 +1,25 @@
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>

View 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;

View file

@ -314,6 +314,11 @@
<tp:docstring>
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>

View 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);

View 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);

View 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)

View 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 *

View 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,

View 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;

View 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:

View 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

View 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;
}

View 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);
}