diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt
index aa5723b..b93556f 100644
--- a/docs/reference/gio/gio-sections.txt
+++ b/docs/reference/gio/gio-sections.txt
@@ -1027,6 +1027,8 @@ g_drive_get_icon
 g_drive_has_volumes
 g_drive_get_volumes
 g_drive_can_eject
+g_drive_can_start
+g_drive_can_stop
 g_drive_can_poll_for_media
 g_drive_poll_for_media
 g_drive_poll_for_media_finish
@@ -1035,6 +1037,10 @@ g_drive_is_media_check_automatic
 g_drive_is_media_removable
 g_drive_eject
 g_drive_eject_finish
+g_drive_start
+g_drive_start_finish
+g_drive_stop
+g_drive_stop_finish
 g_drive_enumerate_identifiers
 g_drive_get_identifier
 <SUBSECTION Standard>
diff --git a/gio/gdrive.c b/gio/gdrive.c
index 9450819..f2a2b91 100644
--- a/gio/gdrive.c
+++ b/gio/gdrive.c
@@ -32,12 +32,12 @@
 
 /**
  * SECTION:gdrive
- * @short_description: Virtual File System drive management
+ * @short_description: Drive management
  * @include: gio/gio.h
- * 
+ *
  * #GDrive - this represent a piece of hardware connected to the machine.
  * It's generally only created for removable hardware or hardware with
- * removable media. 
+ * removable media.
  *
  * #GDrive is a container class for #GVolume objects that stem from
  * the same piece of media. As such, #GDrive abstracts a drive with
@@ -50,6 +50,14 @@
  * as a poll for media operation is potententially expensive and may
  * spin up the drive creating noise.
  *
+ * #GDrive supports starting and stopping drives with authentication
+ * support for the former. This can be used to support a diverse set
+ * of use cases including connecting/disconnecting iSCSI devices,
+ * powering down external disk enclosures and starting/stopping
+ * multi-disk devices such as RAID devices. Note that the actual
+ * semantics and side-effects of starting/stopping a #GDrive may vary
+ * according to implementation.
+ *
  * For porting from GnomeVFS note that there is no equivalent of
  * #GDrive in that API.
  **/
@@ -148,6 +156,23 @@ g_drive_base_init (gpointer g_class)
                     g_cclosure_marshal_VOID__VOID,
                     G_TYPE_NONE, 0);
 
+      /**
+      * GDrive::stop-button:
+      * @drive: a #GDrive.
+      *
+      * Emitted when the physical stop button (if any) of a drive has
+      * been pressed.
+      *
+      * Since: 2.22
+      **/
+      g_signal_new (I_("stop-button"),
+                    G_TYPE_DRIVE,
+                    G_SIGNAL_RUN_LAST,
+                    G_STRUCT_OFFSET (GDriveIface, stop_button),
+                    NULL, NULL,
+                    g_cclosure_marshal_VOID__VOID,
+                    G_TYPE_NONE, 0);
+
       initialized = TRUE;
     }
 }
@@ -542,6 +567,205 @@ g_drive_enumerate_identifiers (GDrive *drive)
   return (* iface->enumerate_identifiers) (drive);
 }
 
+/**
+ * g_drive_can_start:
+ * @drive: a #GDrive.
+ *
+ * Checks if a drive can be started.
+ *
+ * Returns: %TRUE if the @drive can be started, %FALSE otherwise.
+ *
+ * Since: 2.22
+ */
+gboolean
+g_drive_can_start (GDrive *drive)
+{
+  GDriveIface *iface;
+
+  g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
+
+  iface = G_DRIVE_GET_IFACE (drive);
+
+  if (iface->can_start == NULL)
+    return FALSE;
+
+  return (* iface->can_start) (drive);
+}
+
+/**
+ * g_drive_start:
+ * @drive: a #GDrive.
+ * @start_operation: a #GMountOperation or %NULL to avoid user interaction.
+ * @cancellable: optional #GCancellable object, %NULL to ignore.
+ * @callback: a #GAsyncReadyCallback, or %NULL.
+ * @user_data: user data to pass to @callback
+ *
+ * Asynchronously starts a drive.
+ *
+ * When the operation is finished, @callback will be called.
+ * You can then call g_drive_start_finish() to obtain the
+ * result of the operation.
+ *
+ * Since: 2.22
+ */
+void
+g_drive_start (GDrive              *drive,
+               GMountOperation     *start_operation,
+               GCancellable        *cancellable,
+               GAsyncReadyCallback  callback,
+               gpointer             user_data)
+{
+  GDriveIface *iface;
+
+  g_return_if_fail (G_IS_DRIVE (drive));
+
+  iface = G_DRIVE_GET_IFACE (drive);
+
+  if (iface->start == NULL)
+    {
+      g_simple_async_report_error_in_idle (G_OBJECT (drive), callback, user_data,
+					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+					   _("drive doesn't implement start"));
+      return;
+    }
+
+  (* iface->start) (drive, start_operation, cancellable, callback, user_data);
+}
+
+/**
+ * g_drive_start_finish:
+ * @drive: a #GDrive.
+ * @result: a #GAsyncResult.
+ * @error: a #GError, or %NULL
+ *
+ * Finishes starting a drive.
+ *
+ * Returns: %TRUE if the drive has been started successfully,
+ *     %FALSE otherwise.
+ *
+ * Since: 2.22
+ */
+gboolean
+g_drive_start_finish (GDrive         *drive,
+                      GAsyncResult   *result,
+                      GError        **error)
+{
+  GDriveIface *iface;
+
+  g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
+  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+  if (G_IS_SIMPLE_ASYNC_RESULT (result))
+    {
+      GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
+      if (g_simple_async_result_propagate_error (simple, error))
+	return FALSE;
+    }
+
+  iface = G_DRIVE_GET_IFACE (drive);
+
+  return (* iface->start_finish) (drive, result, error);
+}
+
+/**
+ * g_drive_can_stop:
+ * @drive: a #GDrive.
+ *
+ * Checks if a drive can be stopped.
+ *
+ * Returns: %TRUE if the @drive can be stopped, %FALSE otherwise.
+ *
+ * Since: 2.22
+ */
+gboolean
+g_drive_can_stop (GDrive *drive)
+{
+  GDriveIface *iface;
+
+  g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
+
+  iface = G_DRIVE_GET_IFACE (drive);
+
+  if (iface->can_stop == NULL)
+    return FALSE;
+
+  return (* iface->can_stop) (drive);
+}
+
+/**
+ * g_drive_stop:
+ * @drive: a #GDrive.
+ * @flags: flags affecting the unmount if required for stopping.
+ * @cancellable: optional #GCancellable object, %NULL to ignore.
+ * @callback: a #GAsyncReadyCallback, or %NULL.
+ * @user_data: user data to pass to @callback
+ *
+ * Asynchronously stops a drive.
+ *
+ * When the operation is finished, @callback will be called.
+ * You can then call g_drive_stop_finish() to obtain the
+ * result of the operation.
+ *
+ * Since: 2.22
+ */
+void
+g_drive_stop (GDrive               *drive,
+              GMountUnmountFlags    flags,
+              GCancellable         *cancellable,
+              GAsyncReadyCallback   callback,
+              gpointer              user_data)
+{
+  GDriveIface *iface;
+
+  g_return_if_fail (G_IS_DRIVE (drive));
+
+  iface = G_DRIVE_GET_IFACE (drive);
+
+  if (iface->stop == NULL)
+    {
+      g_simple_async_report_error_in_idle (G_OBJECT (drive), callback, user_data,
+					   G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+					   _("drive doesn't implement stop"));
+      return;
+    }
+
+  (* iface->stop) (drive, flags, cancellable, callback, user_data);
+}
+
+/**
+ * g_drive_stop_finish:
+ * @drive: a #GDrive.
+ * @result: a #GAsyncResult.
+ * @error: a #GError, or %NULL
+ *
+ * Finishes stopping a drive.
+ *
+ * Returns: %TRUE if the drive has been stopped successfully,
+ *     %FALSE otherwise.
+ *
+ * Since: 2.22
+ */
+gboolean
+g_drive_stop_finish (GDrive        *drive,
+                     GAsyncResult  *result,
+                     GError       **error)
+{
+  GDriveIface *iface;
+
+  g_return_val_if_fail (G_IS_DRIVE (drive), FALSE);
+  g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
+
+  if (G_IS_SIMPLE_ASYNC_RESULT (result))
+    {
+      GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
+      if (g_simple_async_result_propagate_error (simple, error))
+	return FALSE;
+    }
+
+  iface = G_DRIVE_GET_IFACE (drive);
+
+  return (* iface->stop_finish) (drive, result, error);
+}
 
 #define __G_DRIVE_C__
 #include "gioaliasdef.c"
diff --git a/gio/gdrive.h b/gio/gdrive.h
index e1bc321..32717d9 100644
--- a/gio/gdrive.h
+++ b/gio/gdrive.h
@@ -60,6 +60,13 @@ G_BEGIN_DECLS
  *    the #GDrive doesn't have one.
  * @enumerate_identifiers: Returns an array strings listing the kinds
  *    of identifiers which the #GDrive has.
+ * @can_stop: Returns %TRUE if a #GDrive can be stopped. Since 2.22.
+ * @stop: Stops a #GDrive. Since 2.22.
+ * @stop_finish: Finishes a stop operation. Since 2.22.
+ * @can_start: Returns %TRUE if a #GDrive can be started. Since 2.22.
+ * @start: Starts a #GDrive. Since 2.22.
+ * @start_finish: Finishes a start operation. Since 2.22.
+ * @stop_button: Signal emitted when the physical stop button (if any) of a drive have been pressed. Since 2.22.
  *
  * Interface for creating #GDrive implementations.
  */
@@ -103,6 +110,30 @@ struct _GDriveIface
   char *   (* get_identifier)           (GDrive              *drive,
                                          const char          *kind);
   char **  (* enumerate_identifiers)    (GDrive              *drive);
+
+
+  gboolean (* can_start)                (GDrive              *drive);
+  void     (* start)                    (GDrive              *drive,
+                                         GMountOperation     *start_operation,
+                                         GCancellable        *cancellable,
+                                         GAsyncReadyCallback  callback,
+                                         gpointer             user_data);
+  gboolean (* start_finish)             (GDrive              *drive,
+                                         GAsyncResult        *result,
+                                         GError             **error);
+
+  gboolean (* can_stop)                 (GDrive              *drive);
+  void     (* stop)                     (GDrive              *drive,
+                                         GMountUnmountFlags   flags,
+                                         GCancellable        *cancellable,
+                                         GAsyncReadyCallback  callback,
+                                         gpointer             user_data);
+  gboolean (* stop_finish)              (GDrive              *drive,
+                                         GAsyncResult        *result,
+                                         GError             **error);
+  /* signal, not VFunc */
+  void     (* stop_button)              (GDrive              *drive);
+
 };
 
 GType    g_drive_get_type                 (void) G_GNUC_CONST;
@@ -135,6 +166,26 @@ char *   g_drive_get_identifier           (GDrive              *drive,
 					   const char          *kind);
 char **  g_drive_enumerate_identifiers    (GDrive              *drive);
 
+gboolean g_drive_can_start                (GDrive              *drive);
+void     g_drive_start                    (GDrive              *drive,
+                                           GMountOperation     *start_operation,
+                                           GCancellable        *cancellable,
+                                           GAsyncReadyCallback  callback,
+                                           gpointer             user_data);
+gboolean g_drive_start_finish             (GDrive               *drive,
+                                           GAsyncResult         *result,
+                                           GError              **error);
+
+gboolean g_drive_can_stop                 (GDrive               *drive);
+void     g_drive_stop                     (GDrive               *drive,
+					   GMountUnmountFlags    flags,
+                                           GCancellable         *cancellable,
+                                           GAsyncReadyCallback   callback,
+                                           gpointer              user_data);
+gboolean g_drive_stop_finish              (GDrive               *drive,
+                                           GAsyncResult         *result,
+                                           GError              **error);
+
 G_END_DECLS
 
 #endif /* __G_DRIVE_H__ */
diff --git a/gio/gio.symbols b/gio/gio.symbols
index 89a2e18..a2e6c2c 100644
--- a/gio/gio.symbols
+++ b/gio/gio.symbols
@@ -214,6 +214,12 @@ g_drive_poll_for_media
 g_drive_poll_for_media_finish
 g_drive_get_identifier
 g_drive_enumerate_identifiers
+g_drive_can_start
+g_drive_start
+g_drive_start_finish
+g_drive_can_stop
+g_drive_stop
+g_drive_stop_finish
 #endif
 #endif
 
