Index: uspace/Makefile.common
===================================================================
--- uspace/Makefile.common	(revision 31cca4f32e9a51af49d12c4a23a2adfb951e750c)
+++ uspace/Makefile.common	(revision e160bfe8a5d875ff061225e5b3e77814211c6bff)
@@ -100,7 +100,4 @@
 endif
 
-DEPEND = Makefile.depend
-DEPEND_PREV = $(DEPEND).prev
-
 LIB_PREFIX = $(USPACE_PREFIX)/lib
 
@@ -223,15 +220,15 @@
 endif
 
-.PHONY: all clean
+.PHONY: all clean depend
 
 all: $(VERSION_DEF) $(COMMON_MAKEFILE) $(CONFIG_MAKEFILE) $(CONFIG_HEADER) $(LIBS) $(OUTPUT) $(LOUTPUT) $(EXTRA_OUTPUT)
-	-[ -f $(DEPEND) ] && cp -a $(DEPEND) $(DEPEND_PREV)
 
 all-test: $(TEST_OUTPUT) $(TEST_DISASM)
 
 clean:
-	rm -f $(DEPEND) $(DEPEND_PREV) $(JOB) $(OUTPUT) $(LARCHIVE) $(LOUTPUT) $(EXTRA_OUTPUT) $(EXTRA_CLEAN)
+	rm -f $(JOB) $(OUTPUT) $(LARCHIVE) $(LOUTPUT) $(EXTRA_OUTPUT) $(EXTRA_CLEAN)
 	find . -name '*.o' -follow -exec rm \{\} \;
 	find . -name '*.lo' -follow -exec rm \{\} \;
+	find . -name '*.d' -follow -exec rm \{\} \;
 
 COMMON_CFLAGS = $(INCLUDES_FLAGS) -O$(OPTIMIZATION) -imacros $(CONFIG_HEADER) \
@@ -276,30 +273,12 @@
 JOBFILE = $(LIBC_PREFIX)/../../../tools/jobfile.py
 
-ifeq ($(COMPILER),gcc_cross)
-	CFLAGS += $(COMMON_CFLAGS) $(GCC_CFLAGS)
-	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
-endif
-
-ifeq ($(COMPILER),gcc_helenos)
-	CFLAGS += $(COMMON_CFLAGS) $(GCC_CFLAGS)
-	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
-endif
-
-ifeq ($(COMPILER),gcc_native)
-	CFLAGS += $(COMMON_CFLAGS) $(GCC_CFLAGS)
-	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
-endif
-
 ifeq ($(COMPILER),clang)
 	CFLAGS += $(COMMON_CFLAGS) $(CLANG_CFLAGS)
-	DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
+else
+	CFLAGS += $(COMMON_CFLAGS) $(GCC_CFLAGS)
 endif
 
 LIB_CFLAGS = $(CFLAGS) -fPIC
 LIB_LFLAGS = $(LFLAGS) -shared -soname $(LSONAME) --whole-archive
-
-ifneq ($(MAKECMDGOALS),clean)
--include $(DEPEND)
-endif
 
 AS_CFLAGS := $(addprefix -Xassembler ,$(AFLAGS))
@@ -309,4 +288,7 @@
 LOBJECTS := $(addsuffix .lo,$(basename $(SOURCES)))
 TEST_OBJECTS := $(addsuffix .test.o,$(basename $(TEST_SOURCES)))
+DEPENDS := $(addsuffix .d,$(basename $(SOURCES))) $(addsuffix .test.d,$(basename $(TEST_SOURCES)))
+
+-include $(DEPENDS)
 
 ifneq ($(BINARY),)
@@ -367,50 +349,47 @@
 endif
 
-%.o: %.S $(DEPEND)
-	$(CC) $(DEFS) $(CFLAGS) $(EXTRA_CFLAGS) $(AS_CFLAGS) -D__ASM__ -c $< -o $@
+%.o: %.S | depend
+	$(CC) -MD $(DEFS) $(CFLAGS) $(EXTRA_CFLAGS) $(AS_CFLAGS) -D__ASM__ -c $< -o $@
 ifeq ($(PRECHECK),y)
 	$(JOBFILE) $(JOB) $< $@ as asm/preproc $(DEFS) $(CFLAGS) $(EXTRA_CFLAGS) -D__ASM__
 endif
 
-%.o: %.s $(DEPEND)
-	$(CC) $(DEFS) $(CFLAGS) $(EXTRA_CFLAGS) $(AS_CFLAGS) -D__ASM__ -c $< -o $@
+%.o: %.s | depend
+	$(CC) -MD $(DEFS) $(CFLAGS) $(EXTRA_CFLAGS) $(AS_CFLAGS) -D__ASM__ -c $< -o $@
 ifeq ($(PRECHECK),y)
 	$(JOBFILE) $(JOB) $< $@ as asm
 endif
 
-%.o: %.c $(DEPEND)
-	$(CC) $(DEFS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@
+%.o: %.c | depend
+	$(CC) -MD $(DEFS) $(CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@
 ifeq ($(PRECHECK),y)
 	$(JOBFILE) $(JOB) $< $@ cc core $(DEFS) $(CFLAGS) $(EXTRA_CFLAGS)
 endif
 
-%.test.o: %.c $(DEPEND)
-	$(CC) $(DEFS) $(CFLAGS) $(EXTRA_CFLAGS) $(TEST_CFLAGS) -c $< -o $@
+%.test.o: %.c | depend
+	$(CC) -MD $(DEFS) $(CFLAGS) $(EXTRA_CFLAGS) $(TEST_CFLAGS) -c $< -o $@
 ifeq ($(PRECHECK),y)
 	$(JOBFILE) $(JOB) $< $@ cc core $(DEFS) $(CFLAGS) $(EXTRA_CFLAGS) $(TEST_CFLAGS)
 endif
 
-%.lo: %.S $(DEPEND)
-	$(CC) $(DEFS) $(LIB_CFLAGS) $(EXTRA_CFLAGS) $(AS_CFLAGS) -D__ASM__ -c $< -o $@
+%.lo: %.S | depend
+	$(CC) -MD $(DEFS) $(LIB_CFLAGS) $(EXTRA_CFLAGS) $(AS_CFLAGS) -D__ASM__ -c $< -o $@
 ifeq ($(PRECHECK),y)
 	$(JOBFILE) $(JOB) $< $@ as asm/preproc $(DEFS) $(LIB_CFLAGS) $(EXTRA_CFLAGS) -D__ASM__
 endif
 
-%.lo: %.s $(DEPEND)
-	$(CC) $(DEFS) $(LIB_CFLAGS) $(EXTRA_CFLAGS) $(AS_CFLAGS) -D__ASM__ -c $< -o $@
+%.lo: %.s | depend
+	$(CC) -MD $(DEFS) $(LIB_CFLAGS) $(EXTRA_CFLAGS) $(AS_CFLAGS) -D__ASM__ -c $< -o $@
 ifeq ($(PRECHECK),y)
 	$(JOBFILE) $(JOB) $< $@ as asm
 endif
 
-%.lo: %.c $(DEPEND)
-	$(CC) $(DEFS) $(LIB_CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@
+%.lo: %.c | depend
+	$(CC) -MD $(DEFS) $(LIB_CFLAGS) $(EXTRA_CFLAGS) -c $< -o $@
 ifeq ($(PRECHECK),y)
 	$(JOBFILE) $(JOB) $< $@ cc core $(DEFS) $(LIB_CFLAGS) $(EXTRA_CFLAGS)
 endif
 
-$(DEPEND): $(PRE_DEPEND)
-	makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) $(EXTRA_CFLAGS) -- $(SOURCES) > $@ 2> /dev/null
-	makedepend -f - -o.test.o -- $(DEPEND_DEFS) $(CFLAGS) $(EXTRA_CFLAGS) $(TEST_CFLAGS) -- $(TEST_SOURCES) >> $@ 2> /dev/null
-	-[ -f $(DEPEND_PREV) ] && diff -q $(DEPEND_PREV) $@ && mv -f $(DEPEND_PREV) $@
+depend: $(PRE_DEPEND)
 
 ##
Index: uspace/app/devctl/devctl.c
===================================================================
--- uspace/app/devctl/devctl.c	(revision 31cca4f32e9a51af49d12c4a23a2adfb951e750c)
+++ uspace/app/devctl/devctl.c	(revision e160bfe8a5d875ff061225e5b3e77814211c6bff)
@@ -337,4 +337,24 @@
 }
 
+static int drv_unload(const char *drvname)
+{
+	int rc;
+	devman_handle_t drvh;
+
+	rc = devman_driver_get_handle(drvname, &drvh);
+	if (rc != EOK) {
+		printf("Failed resolving driver '%s' (%d).\n", drvname, rc);
+		return rc;
+	}
+
+	rc = devman_driver_unload(drvh);
+	if (rc != EOK) {
+		printf("Failed unloading driver '%s' (%d).\n", drvname, rc);
+		return rc;
+	}
+
+	return EOK;
+}
+
 static void print_syntax(void)
 {
@@ -346,4 +366,5 @@
 	printf("\tdevctl show-drv <driver-name>\n");
 	printf("\tdevctl load-drv <driver-name>\n");
+	printf("\tdevctl unload-drv <driver-name>\n");
 }
 
@@ -412,4 +433,14 @@
 		if (rc != EOK)
 			return 2;
+	} else if (str_cmp(argv[1], "unload-drv") == 0) {
+		if (argc < 3) {
+			printf(NAME ": Argument missing.\n");
+			print_syntax();
+			return 1;
+		}
+
+		rc = drv_unload(argv[2]);
+		if (rc != EOK)
+			return 2;
 	} else {
 		printf(NAME ": Invalid argument '%s'.\n", argv[1]);
Index: uspace/lib/c/generic/devman.c
===================================================================
--- uspace/lib/c/generic/devman.c	(revision 31cca4f32e9a51af49d12c4a23a2adfb951e750c)
+++ uspace/lib/c/generic/devman.c	(revision e160bfe8a5d875ff061225e5b3e77814211c6bff)
@@ -719,4 +719,16 @@
 }
 
+int devman_driver_unload(devman_handle_t drvh)
+{
+	async_exch_t *exch = devman_exchange_begin(INTERFACE_DDF_CLIENT);
+	if (exch == NULL)
+		return ENOMEM;
+	
+	int rc = async_req_1_0(exch, DEVMAN_DRIVER_UNLOAD, drvh);
+	
+	devman_exchange_end(exch);
+	return rc;
+}
+
 /** @}
  */
Index: uspace/lib/c/include/devman.h
===================================================================
--- uspace/lib/c/include/devman.h	(revision 31cca4f32e9a51af49d12c4a23a2adfb951e750c)
+++ uspace/lib/c/include/devman.h	(revision e160bfe8a5d875ff061225e5b3e77814211c6bff)
@@ -82,4 +82,5 @@
 extern int devman_driver_get_state(devman_handle_t, driver_state_t *);
 extern int devman_driver_load(devman_handle_t);
+extern int devman_driver_unload(devman_handle_t);
 
 #endif
Index: uspace/lib/c/include/ipc/devman.h
===================================================================
--- uspace/lib/c/include/ipc/devman.h	(revision 31cca4f32e9a51af49d12c4a23a2adfb951e750c)
+++ uspace/lib/c/include/ipc/devman.h	(revision e160bfe8a5d875ff061225e5b3e77814211c6bff)
@@ -156,4 +156,5 @@
 	DRIVER_FUN_ONLINE,
 	DRIVER_FUN_OFFLINE,
+	DRIVER_STOP
 } devman_to_driver_t;
 
@@ -176,5 +177,6 @@
 	DEVMAN_DRIVER_GET_NAME,
 	DEVMAN_DRIVER_GET_STATE,
-	DEVMAN_DRIVER_LOAD
+	DEVMAN_DRIVER_LOAD,
+	DEVMAN_DRIVER_UNLOAD
 } client_to_devman_t;
 
Index: uspace/lib/drv/generic/driver.c
===================================================================
--- uspace/lib/drv/generic/driver.c	(revision 31cca4f32e9a51af49d12c4a23a2adfb951e750c)
+++ uspace/lib/drv/generic/driver.c	(revision e160bfe8a5d875ff061225e5b3e77814211c6bff)
@@ -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:
Index: uspace/srv/devman/client_conn.c
===================================================================
--- uspace/srv/devman/client_conn.c	(revision 31cca4f32e9a51af49d12c4a23a2adfb951e750c)
+++ uspace/srv/devman/client_conn.c	(revision e160bfe8a5d875ff061225e5b3e77814211c6bff)
@@ -726,4 +726,23 @@
 }
 
+/** Unload a driver by user request. */
+static void devman_driver_unload(ipc_callid_t iid, ipc_call_t *icall)
+{
+	driver_t *drv;
+	int rc;
+	
+	drv = driver_find(&drivers_list, IPC_GET_ARG1(*icall));
+	if (drv == NULL) {
+		async_answer_0(iid, ENOENT);
+		return;
+	}
+	
+	fibril_mutex_lock(&drv->driver_mutex);
+	rc = stop_driver(drv);
+	fibril_mutex_unlock(&drv->driver_mutex);
+
+	async_answer_0(iid, rc);
+}
+
 /** Function for handling connections from a client to the device manager. */
 void devman_connection_client(ipc_callid_t iid, ipc_call_t *icall, void *arg)
@@ -794,4 +813,7 @@
 			devman_driver_load(callid, &call);
 			break;
+		case DEVMAN_DRIVER_UNLOAD:
+			devman_driver_unload(callid, &call);
+			break;
 		default:
 			async_answer_0(callid, ENOENT);
Index: uspace/srv/devman/driver.c
===================================================================
--- uspace/srv/devman/driver.c	(revision 31cca4f32e9a51af49d12c4a23a2adfb951e750c)
+++ uspace/srv/devman/driver.c	(revision e160bfe8a5d875ff061225e5b3e77814211c6bff)
@@ -298,4 +298,30 @@
 	drv->state = DRIVER_STARTING;
 	return true;
+}
+
+/** Stop a driver
+ *
+ * @param drv		The driver's structure.
+ * @return		True if the driver's task is successfully spawned, false
+ *			otherwise.
+ */
+int stop_driver(driver_t *drv)
+{
+	async_exch_t *exch;
+	sysarg_t retval;
+	
+	log_msg(LOG_DEFAULT, LVL_DEBUG, "stop_driver(drv=\"%s\")", drv->name);
+
+	exch = async_exchange_begin(drv->sess);
+	retval = async_req_0_0(exch, DRIVER_STOP);
+	loc_exchange_end(exch);
+	
+	if (retval != EOK)
+		return retval;
+	
+	drv->state = DRIVER_NOT_STARTED;
+	async_hangup(drv->sess);
+	drv->sess = NULL;
+	return EOK;
 }
 
Index: uspace/srv/devman/driver.h
===================================================================
--- uspace/srv/devman/driver.h	(revision 31cca4f32e9a51af49d12c4a23a2adfb951e750c)
+++ uspace/srv/devman/driver.h	(revision e160bfe8a5d875ff061225e5b3e77814211c6bff)
@@ -50,4 +50,5 @@
 extern void detach_driver(dev_tree_t *, dev_node_t *);
 extern bool start_driver(driver_t *);
+extern int stop_driver(driver_t *);
 extern void add_device(driver_t *, dev_node_t *, dev_tree_t *);
 extern int driver_dev_remove(dev_tree_t *, dev_node_t *);
