Index: uspace/srv/volsrv/meson.build
===================================================================
--- uspace/srv/volsrv/meson.build	(revision ca127f376913ff2f1ec26a21284d73a42ef51816)
+++ uspace/srv/volsrv/meson.build	(revision 94ea2e3771e36d7eaa5eef3ba668b8f14e4c2291)
@@ -1,4 +1,4 @@
 #
-# Copyright (c) 2015 Jiri Svoboda
+# Copyright (c) 2025 Jiri Svoboda
 # All rights reserved.
 #
@@ -27,5 +27,5 @@
 #
 
-deps = [ 'block', 'label', 'sif' ]
+deps = [ 'block', 'device', 'label', 'sif' ]
 
 src = files(
Index: uspace/srv/volsrv/part.c
===================================================================
--- uspace/srv/volsrv/part.c	(revision ca127f376913ff2f1ec26a21284d73a42ef51816)
+++ uspace/srv/volsrv/part.c	(revision 94ea2e3771e36d7eaa5eef3ba668b8f14e4c2291)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2024 Jiri Svoboda
+ * Copyright (c) 2025 Jiri Svoboda
  * All rights reserved.
  *
@@ -36,4 +36,5 @@
 
 #include <adt/list.h>
+#include <bd.h>
 #include <errno.h>
 #include <fibril_synch.h>
@@ -642,5 +643,38 @@
 }
 
-errno_t vol_part_eject_part(vol_part_t *part)
+static errno_t vol_part_eject_device(service_id_t svcid)
+{
+	async_sess_t *sess;
+	errno_t rc;
+	bd_t *bd;
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_eject_device(%zu)",
+	    (size_t)svcid);
+
+	sess = loc_service_connect(svcid, INTERFACE_BLOCK, 0);
+	if (sess == NULL)
+		return EIO;
+
+	rc = bd_open(sess, &bd);
+	if (rc != EOK) {
+		async_hangup(sess);
+		return EIO;
+	}
+
+	rc = bd_eject(bd);
+	if (rc != EOK) {
+		log_msg(LOG_DEFAULT, LVL_WARN, "vol_part_eject_device(): "
+		    "eject fail");
+		bd_close(bd);
+		async_hangup(sess);
+		return EIO;
+	}
+
+	bd_close(bd);
+	async_hangup(sess);
+	return EOK;
+}
+
+errno_t vol_part_eject_part(vol_part_t *part, vol_eject_flags_t flags)
 {
 	int rc;
@@ -667,4 +701,12 @@
 			log_msg(LOG_DEFAULT, LVL_ERROR, "Failed deleting "
 			    "mount directory %s.", part->cur_mp);
+		}
+	}
+
+	if ((flags & vef_physical) != 0) {
+		rc = vol_part_eject_device(part->svc_id);
+		if (rc != EOK) {
+			log_msg(LOG_DEFAULT, LVL_ERROR, "Failed physically "
+			    "ejecting device %s.", part->svc_name);
 		}
 	}
@@ -819,5 +861,5 @@
 
 	if (part->cur_mp != NULL) {
-		rc = vol_part_eject_part(part);
+		rc = vol_part_eject_part(part, vef_none);
 		if (rc != EOK)
 			return rc;
Index: uspace/srv/volsrv/part.h
===================================================================
--- uspace/srv/volsrv/part.h	(revision ca127f376913ff2f1ec26a21284d73a42ef51816)
+++ uspace/srv/volsrv/part.h	(revision 94ea2e3771e36d7eaa5eef3ba668b8f14e4c2291)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2015 Jiri Svoboda
+ * Copyright (c) 2025 Jiri Svoboda
  * All rights reserved.
  *
@@ -55,5 +55,5 @@
     vol_part_t **);
 extern void vol_part_del_ref(vol_part_t *);
-extern errno_t vol_part_eject_part(vol_part_t *);
+extern errno_t vol_part_eject_part(vol_part_t *, vol_eject_flags_t);
 extern errno_t vol_part_empty_part(vol_part_t *);
 extern errno_t vol_part_insert_part(vol_part_t *);
Index: uspace/srv/volsrv/volsrv.c
===================================================================
--- uspace/srv/volsrv/volsrv.c	(revision ca127f376913ff2f1ec26a21284d73a42ef51816)
+++ uspace/srv/volsrv/volsrv.c	(revision 94ea2e3771e36d7eaa5eef3ba668b8f14e4c2291)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2024 Jiri Svoboda
+ * Copyright (c) 2025 Jiri Svoboda
  * All rights reserved.
  *
@@ -205,9 +205,13 @@
 {
 	service_id_t sid;
+	vol_eject_flags_t flags;
 	vol_part_t *part;
 	errno_t rc;
 
 	sid = ipc_get_arg1(icall);
-	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_eject_srv(%zu)", sid);
+	flags = ipc_get_arg2(icall);
+
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "vol_part_eject_srv(%zu, %x)",
+	    sid, flags);
 
 	rc = vol_part_find_by_id_ref(parts, sid, &part);
@@ -217,5 +221,5 @@
 	}
 
-	rc = vol_part_eject_part(part);
+	rc = vol_part_eject_part(part, flags);
 	if (rc != EOK) {
 		async_answer_0(icall, EIO);
