Index: uspace/lib/drv/generic/driver.c
===================================================================
--- uspace/lib/drv/generic/driver.c	(revision d51838f190d8e49cb00493b84858f7ad93996014)
+++ uspace/lib/drv/generic/driver.c	(revision feab36ae506549c27d8f55556337394648907d2b)
@@ -68,4 +68,7 @@
 FIBRIL_MUTEX_INITIALIZE(functions_mutex);
 
+FIBRIL_RWLOCK_INITIALIZE(stopping_lock);
+static bool stopping = false;
+
 static ddf_dev_t *create_device(void);
 static void delete_device(ddf_dev_t *);
@@ -127,6 +130,15 @@
 	}
 	
+	fibril_rwlock_read_lock(&stopping_lock);
+
+	if (stopping) {
+		fibril_rwlock_read_unlock(&stopping_lock);
+		async_answer_0(iid, EIO);
+		return;
+	}
+	
 	ddf_dev_t *dev = create_device();
 	if (!dev) {
+		fibril_rwlock_read_unlock(&stopping_lock);
 		free(dev_name);
 		async_answer_0(iid, ENOMEM);
@@ -148,4 +160,5 @@
 	
 	if (res != EOK) {
+		fibril_rwlock_read_unlock(&stopping_lock);
 		dev_del_ref(dev);
 		async_answer_0(iid, res);
@@ -156,4 +169,5 @@
 	list_append(&dev->link, &devices);
 	fibril_mutex_unlock(&devices_mutex);
+	fibril_rwlock_read_unlock(&stopping_lock);
 	
 	async_answer_0(iid, res);
@@ -282,4 +296,33 @@
 	
 	async_answer_0(iid, (sysarg_t) rc);
+}
+
+static void driver_stop(ipc_callid_t iid, ipc_call_t *icall)
+{
+	/* Prevent new devices from being added */
+	fibril_rwlock_write_lock(&stopping_lock);
+	stopping = true;
+
+	/* Check if there are any devices */
+	fibril_mutex_lock(&devices_mutex);
+	if (list_first(&devices) != NULL) {
+		/* Devices exist, roll back */
+		fibril_mutex_unlock(&devices_mutex);
+		stopping = false;
+		fibril_rwlock_write_unlock(&stopping_lock);
+		async_answer_0(iid, EBUSY);
+		return;
+	}
+
+	fibril_rwlock_write_unlock(&stopping_lock);
+
+	/* There should be no functions at this point */
+	fibril_mutex_lock(&functions_mutex);
+	assert(list_first(&functions) == NULL);
+	fibril_mutex_unlock(&functions_mutex);
+
+	/* Reply with success and terminate */
+	async_answer_0(iid, EOK);
+	exit(0);
 }
 
@@ -312,4 +355,7 @@
 		case DRIVER_FUN_OFFLINE:
 			driver_fun_offline(callid, &call);
+			break;
+		case DRIVER_STOP:
+			driver_stop(callid, &call);
 			break;
 		default:
