Hi Denis,

2010/4/1 Denis Kenzior <[email protected]>:
>> What we miss from the core is a way to do asynchronous cleanup
>> (separate from Powered). A shutdown() method in modem driver and
>> corresponding callback, like ofono_modem_shutdown_ready(). This way we
>> can do what ever N900 requires us to do and there is no need to touch
>> other drivers.
>
> Send a patch with your proposal.

Attached.

>  So far I like the idea of disable having a
> hint on whether a shutdown is in progress more than an explicit shutdown
> method.

That is also possible, but then we need also more power states
(besides off and on).

-- 
Pekka.Pessi mail at nokia.com
From 203c98e8f9932bce3a914b0255f2ad5c92c7bffe Mon Sep 17 00:00:00 2001
From: Pekka Pessi <[email protected]>
Date: Mon, 12 Apr 2010 17:00:35 +0300
Subject: [PATCH] Added ofono_modem_set_ready_to_shutdown(), shutdown method to driver.

Ensure all modems are ready to shutdown before terminating daemon.
---
 include/modem.h |    5 +++++
 src/modem.c     |   51 ++++++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 47 insertions(+), 9 deletions(-)

diff --git a/include/modem.h b/include/modem.h
index d502640..cd6bf9e 100644
--- a/include/modem.h
+++ b/include/modem.h
@@ -50,6 +50,8 @@ void ofono_modem_remove(struct ofono_modem *modem);
 void ofono_modem_set_powered(struct ofono_modem *modem, ofono_bool_t powered);
 ofono_bool_t ofono_modem_get_powered(struct ofono_modem *modem);
 
+void ofono_modem_set_ready_to_shutdown(struct ofono_modem *modem);
+
 void ofono_modem_set_name(struct ofono_modem *modem, const char *name);
 
 int ofono_modem_set_string(struct ofono_modem *modem,
@@ -85,6 +87,9 @@ struct ofono_modem_driver {
 
 	/* Populate the atoms that are available with SIM / Unlocked SIM*/
 	void (*post_sim)(struct ofono_modem *modem);
+
+	/* Prepare device for remove */
+	int (*shutdown)(struct ofono_modem *modem);
 };
 
 int ofono_modem_driver_register(const struct ofono_modem_driver *);
diff --git a/src/modem.c b/src/modem.c
index b935328..cb99303 100644
--- a/src/modem.c
+++ b/src/modem.c
@@ -40,7 +40,6 @@ static GSList *g_modem_list = NULL;
 
 static int next_modem_id = 0;
 static gboolean powering_down = FALSE;
-static int modems_remaining = 0;
 
 enum ofono_property_type {
 	OFONO_PROPERTY_TYPE_INVALID = 0,
@@ -59,6 +58,7 @@ struct ofono_modem {
 	guint			interface_update;
 	ofono_bool_t		powered;
 	ofono_bool_t		powered_pending;
+	ofono_bool_t            ready_to_shutdown;
 	guint			timeout;
 	GHashTable		*properties;
 	struct ofono_sim	*sim;
@@ -597,12 +597,8 @@ void ofono_modem_set_powered(struct ofono_modem *modem, ofono_bool_t powered)
 		}
 	}
 
-	if (powering_down && powered == FALSE) {
-		modems_remaining -= 1;
-
-		if (modems_remaining == 0)
-			__ofono_exit();
-	}
+	if (powering_down && powered == FALSE)
+		__ofono_modem_shutdown();
 }
 
 ofono_bool_t ofono_modem_get_powered(struct ofono_modem *modem)
@@ -613,6 +609,14 @@ ofono_bool_t ofono_modem_get_powered(struct ofono_modem *modem)
 	return modem->powered;
 }
 
+void ofono_modem_set_ready_to_shutdown(struct ofono_modem *modem)
+{
+	modem->ready_to_shutdown = TRUE;
+
+	if (powering_down)
+		__ofono_modem_shutdown();
+}
+
 static gboolean trigger_interface_update(void *data)
 {
 	struct ofono_modem *modem = data;
@@ -1298,10 +1302,24 @@ void ofono_modem_driver_unregister(const struct ofono_modem_driver *d)
 	}
 }
 
+static int modem_shutdown(struct ofono_modem *modem)
+{
+	const struct ofono_modem_driver *driver = modem->driver;
+
+	if (driver && driver->shutdown)
+		return driver->shutdown(modem);
+
+	modem->ready_to_shutdown = TRUE;
+	return 0;
+}
+
 void __ofono_modem_shutdown()
 {
 	struct ofono_modem *modem;
 	GSList *l;
+	gboolean already = powering_down;
+	int modems_remaining = 0;
+	int error;
 
 	powering_down = TRUE;
 
@@ -1311,11 +1329,26 @@ void __ofono_modem_shutdown()
 		if (modem->driver == NULL)
 			continue;
 
+		if (already) {
+			if (!modem->ready_to_shutdown)
+				return;
+			if (modem->powered)
+				return;
+			continue;
+		}
+
+		error = modem_shutdown(modem);
+		if (error == -EINPROGRESS) {
+			modems_remaining++;
+			continue;
+		}
+
 		if (modem->powered == FALSE && modem->powered_pending == FALSE)
 			continue;
 
-		if (set_powered(modem, FALSE) == -EINPROGRESS)
-			modems_remaining += 1;
+		error = set_powered(modem, FALSE);
+		if (error == -EINPROGRESS || error == -EALREADY)
+			modems_remaining++;
 	}
 
 	if (modems_remaining == 0)
-- 
1.6.3.3

_______________________________________________
ofono mailing list
[email protected]
http://lists.ofono.org/listinfo/ofono

Reply via email to