Index: uspace/app/trace/ipc_desc.c
===================================================================
--- uspace/app/trace/ipc_desc.c	(revision d076f1609141fd03fa25c7138c9260c1f6d19dbf)
+++ uspace/app/trace/ipc_desc.c	(revision 300f4c4dd43b87fb910ea1cfccdc3280c2bdd2ca)
@@ -40,6 +40,4 @@
 	/* System methods */
 	{ IPC_M_PHONE_HUNGUP,     "PHONE_HUNGUP" },
-	{ IPC_M_CONNECTION_CLONE, "CONNECTION_CLONE" },
-	{ IPC_M_CLONE_ESTABLISH,  "CLONE_ESTABLISH" },
 	{ IPC_M_CONNECT_ME_TO,    "CONNECT_ME_TO" },
 	{ IPC_M_CONNECT_TO_ME,    "CONNECT_TO_ME" },
Index: uspace/drv/audio/hdaudio/hdaudio.c
===================================================================
--- uspace/drv/audio/hdaudio/hdaudio.c	(revision d076f1609141fd03fa25c7138c9260c1f6d19dbf)
+++ uspace/drv/audio/hdaudio/hdaudio.c	(revision 300f4c4dd43b87fb910ea1cfccdc3280c2bdd2ca)
@@ -263,7 +263,8 @@
 	}
 
-	rc = register_interrupt_handler(dev, res.irqs.irqs[0],
+	int irq_cap = register_interrupt_handler(dev, res.irqs.irqs[0],
 	    hdaudio_interrupt, &irq_code);
-	if (rc != EOK) {
+	if (irq_cap < 0) {
+		rc = irq_cap;
 		ddf_msg(LVL_ERROR, "Failed registering interrupt handler. (%d)",
 		    rc);
Index: uspace/drv/audio/sb16/main.c
===================================================================
--- uspace/drv/audio/sb16/main.c	(revision d076f1609141fd03fa25c7138c9260c1f6d19dbf)
+++ uspace/drv/audio/sb16/main.c	(revision 300f4c4dd43b87fb910ea1cfccdc3280c2bdd2ca)
@@ -94,4 +94,5 @@
 	irq_cmd_t irq_cmds[irq_cmd_count];
 	irq_pio_range_t irq_ranges[1];
+	int irq_cap;
 
 	sb16_t *soft_state = ddf_dev_data_alloc(device, sizeof(sb16_t));
@@ -123,6 +124,8 @@
 	};
 
-	rc = register_interrupt_handler(device, irq, irq_handler, &irq_code);
-	if (rc != EOK) {
+	irq_cap = register_interrupt_handler(device, irq, irq_handler,
+	    &irq_code);
+	if (irq_cap < 0) {
+		rc = irq_cap;
 		ddf_log_error("Failed to register irq handler: %s.",
 		    str_error(rc));
@@ -168,5 +171,5 @@
 error:
 	if (handler_regd)
-		unregister_interrupt_handler(device, irq);
+		unregister_interrupt_handler(device, irq_cap);
 	return rc;
 }
Index: uspace/drv/block/ahci/ahci.c
===================================================================
--- uspace/drv/block/ahci/ahci.c	(revision d076f1609141fd03fa25c7138c9260c1f6d19dbf)
+++ uspace/drv/block/ahci/ahci.c	(revision 300f4c4dd43b87fb910ea1cfccdc3280c2bdd2ca)
@@ -1185,12 +1185,12 @@
 	ct.ranges = ahci_ranges;
 	
-	int rc = register_interrupt_handler(dev, hw_res_parsed.irqs.irqs[0],
-	    ahci_interrupt, &ct);
-	if (rc != EOK) {
+	int irq_cap = register_interrupt_handler(dev,
+	    hw_res_parsed.irqs.irqs[0], ahci_interrupt, &ct);
+	if (irq_cap < 0) {
 		ddf_msg(LVL_ERROR, "Failed registering interrupt handler.");
 		goto error_register_interrupt_handler;
 	}
 	
-	rc = irc_enable_interrupt(hw_res_parsed.irqs.irqs[0]);
+	int rc = irc_enable_interrupt(hw_res_parsed.irqs.irqs[0]);
 	if (rc != EOK) {
 		ddf_msg(LVL_ERROR, "Failed enable interupt.");
@@ -1202,5 +1202,5 @@
 	
 error_enable_interrupt:
-	unregister_interrupt_handler(dev, hw_res_parsed.irqs.irqs[0]);
+	unregister_interrupt_handler(dev, irq_cap);
 	
 error_register_interrupt_handler:
Index: uspace/drv/block/ddisk/ddisk.c
===================================================================
--- uspace/drv/block/ddisk/ddisk.c	(revision d076f1609141fd03fa25c7138c9260c1f6d19dbf)
+++ uspace/drv/block/ddisk/ddisk.c	(revision 300f4c4dd43b87fb910ea1cfccdc3280c2bdd2ca)
@@ -112,4 +112,6 @@
 	ddisk_regs_t *ddisk_regs;
 
+	int irq_cap;
+
 	bd_srvs_t bds;
 } ddisk_t;
@@ -447,4 +449,6 @@
 	ddisk->bds.sarg = ddisk;
 
+	ddisk->irq_cap = -1;
+
 	/*
 	 * Enable access to ddisk's PIO registers.
@@ -499,7 +503,8 @@
 	ddisk_irq_commands[0].addr = (void *) &res_phys->status;
 	ddisk_irq_commands[3].addr = (void *) &res_phys->command;
-	rc = register_interrupt_handler(dev, ddisk->ddisk_res.irq,
+	ddisk->irq_cap = register_interrupt_handler(dev, ddisk->ddisk_res.irq,
 	    ddisk_irq_handler, &ddisk_irq_code);
-	if (rc != EOK) {
+	if (ddisk->irq_cap < 0) {
+		rc = ddisk->irq_cap;
 		ddf_msg(LVL_ERROR, "Failed to register interrupt handler.");
 		goto error;
@@ -541,5 +546,5 @@
 	}
 
-	unregister_interrupt_handler(ddisk->dev, ddisk->ddisk_res.irq);
+	unregister_interrupt_handler(ddisk->dev, ddisk->irq_cap);
 	
 	rc = pio_disable(ddisk->ddisk_regs, sizeof(ddisk_regs_t));
Index: uspace/drv/char/i8042/i8042.c
===================================================================
--- uspace/drv/char/i8042/i8042.c	(revision d076f1609141fd03fa25c7138c9260c1f6d19dbf)
+++ uspace/drv/char/i8042/i8042.c	(revision 300f4c4dd43b87fb910ea1cfccdc3280c2bdd2ca)
@@ -269,7 +269,8 @@
 	};
 	
-	rc = register_interrupt_handler(ddf_dev, irq_kbd, i8042_irq_handler,
-	    &irq_code);
-	if (rc != EOK) {
+	const int irq_kbd_cap = register_interrupt_handler(ddf_dev, irq_kbd,
+	    i8042_irq_handler, &irq_code);
+	if (irq_kbd_cap < 0) {
+		rc = irq_kbd_cap;
 		ddf_msg(LVL_ERROR, "Failed set handler for kbd: %s.",
 		    ddf_dev_get_name(ddf_dev));
@@ -277,7 +278,8 @@
 	}
 	
-	rc = register_interrupt_handler(ddf_dev, irq_mouse, i8042_irq_handler,
-	    &irq_code);
-	if (rc != EOK) {
+	const int irq_mouse_cap = register_interrupt_handler(ddf_dev, irq_mouse,
+	    i8042_irq_handler, &irq_code);
+	if (irq_mouse_cap < 0) {
+		rc = irq_mouse_cap;
 		ddf_msg(LVL_ERROR, "Failed set handler for mouse: %s.",
 		    ddf_dev_get_name(ddf_dev));
Index: uspace/drv/char/ns8250/ns8250.c
===================================================================
--- uspace/drv/char/ns8250/ns8250.c	(revision d076f1609141fd03fa25c7138c9260c1f6d19dbf)
+++ uspace/drv/char/ns8250/ns8250.c	(revision 300f4c4dd43b87fb910ea1cfccdc3280c2bdd2ca)
@@ -160,4 +160,6 @@
 	/** The irq assigned to this device. */
 	int irq;
+	/** IRQ capability handle */
+	int irq_cap;
 	/** The base i/o address of the devices registers. */
 	uintptr_t io_addr;
@@ -797,5 +799,5 @@
 static inline int ns8250_unregister_interrupt_handler(ns8250_t *ns)
 {
-	return unregister_interrupt_handler(ns->dev, ns->irq);
+	return unregister_interrupt_handler(ns->dev, ns->irq_cap);
 }
 
@@ -849,5 +851,6 @@
 	
 	/* Register interrupt handler. */
-	if (ns8250_register_interrupt_handler(ns) != EOK) {
+	ns->irq_cap = ns8250_register_interrupt_handler(ns);
+	if (ns->irq_cap < 0) {
 		ddf_msg(LVL_ERROR, "Failed to register interrupt handler.");
 		rc = EADDRNOTAVAIL;
Index: uspace/drv/char/pl050/pl050.c
===================================================================
--- uspace/drv/char/pl050/pl050.c	(revision d076f1609141fd03fa25c7138c9260c1f6d19dbf)
+++ uspace/drv/char/pl050/pl050.c	(revision 300f4c4dd43b87fb910ea1cfccdc3280c2bdd2ca)
@@ -212,7 +212,8 @@
 	pl050->regs = regs;
 
-	rc = register_interrupt_handler(pl050->dev, res.irqs.irqs[0],
-	    pl050_interrupt, &pl050_irq_code);
-	if (rc != EOK) {
+	const int irq_cap = register_interrupt_handler(pl050->dev,
+	    res.irqs.irqs[0], pl050_interrupt, &pl050_irq_code);
+	if (irq_cap < 0) {
+		rc = irq_cap;
 		ddf_msg(LVL_ERROR, "Failed registering interrupt handler. (%d)",
 		    rc);
Index: uspace/drv/nic/e1k/e1k.c
===================================================================
--- uspace/drv/nic/e1k/e1k.c	(revision d076f1609141fd03fa25c7138c9260c1f6d19dbf)
+++ uspace/drv/nic/e1k/e1k.c	(revision 300f4c4dd43b87fb910ea1cfccdc3280c2bdd2ca)
@@ -1253,5 +1253,5 @@
  * @param nic Driver data
  *
- * @return EOK if the handler was registered
+ * @return IRQ capability handle if the handler was registered
  * @return Negative error code otherwise
  *
@@ -1268,9 +1268,9 @@
 	e1000_irq_code.cmds[2].addr = e1000->reg_base_phys + E1000_IMC;
 	
-	int rc = register_interrupt_handler(nic_get_ddf_dev(nic),
-	    e1000->irq, e1000_interrupt_handler, &e1000_irq_code);
+	int cap = register_interrupt_handler(nic_get_ddf_dev(nic), e1000->irq,
+	    e1000_interrupt_handler, &e1000_irq_code);
 	
 	fibril_mutex_unlock(&irq_reg_mutex);
-	return rc;
+	return cap;
 }
 
@@ -2152,7 +2152,9 @@
 	ddf_fun_set_ops(fun, &e1000_dev_ops);
 	
-	rc = e1000_register_int_handler(nic);
-	if (rc != EOK)
+	int irq_cap = e1000_register_int_handler(nic);
+	if (irq_cap < 0) {
+		rc = irq_cap;
 		goto err_fun_create;
+	}
 	
 	rc = e1000_initialize_rx_structure(nic);
@@ -2189,5 +2191,5 @@
 	e1000_uninitialize_rx_structure(nic);
 err_irq:
-	unregister_interrupt_handler(dev, DRIVER_DATA_DEV(dev)->irq);
+	unregister_interrupt_handler(dev, irq_cap);
 err_fun_create:
 	ddf_fun_destroy(fun);
Index: uspace/drv/nic/ne2k/ne2k.c
===================================================================
--- uspace/drv/nic/ne2k/ne2k.c	(revision d076f1609141fd03fa25c7138c9260c1f6d19dbf)
+++ uspace/drv/nic/ne2k/ne2k.c	(revision 300f4c4dd43b87fb910ea1cfccdc3280c2bdd2ca)
@@ -160,7 +160,7 @@
 	}
 
-	int rc = register_interrupt_handler(nic_get_ddf_dev(nic_data),
+	int irq_cap = register_interrupt_handler(nic_get_ddf_dev(nic_data),
 		ne2k->irq, ne2k_interrupt_handler, &ne2k->code);
-	return rc;
+	return irq_cap;
 }
 
@@ -228,6 +228,6 @@
 	ne2k->probed = true;
 	
-	rc = ne2k_register_interrupt(nic_data);
-	if (rc != EOK)
+	int irq_cap = ne2k_register_interrupt(nic_data);
+	if (irq_cap < 0)
 		return EINVAL;
 	
Index: uspace/drv/nic/rtl8139/driver.c
===================================================================
--- uspace/drv/nic/rtl8139/driver.c	(revision d076f1609141fd03fa25c7138c9260c1f6d19dbf)
+++ uspace/drv/nic/rtl8139/driver.c	(revision 300f4c4dd43b87fb910ea1cfccdc3280c2bdd2ca)
@@ -881,5 +881,6 @@
  *  @param nic_data  The driver data
  *
- *  @return EOK if the handler was registered, negative error code otherwise
+ *  @return IRQ capability handle if the handler was registered.
+ *  @return Negative error code otherwise.
  */
 inline static int rtl8139_register_int_handler(nic_t *nic_data)
@@ -894,10 +895,10 @@
 	rtl8139_irq_code.cmds[2].addr = rtl8139->io_addr + ISR;
 	rtl8139_irq_code.cmds[3].addr = rtl8139->io_addr + IMR;
-	int rc = register_interrupt_handler(nic_get_ddf_dev(nic_data),
+	int cap = register_interrupt_handler(nic_get_ddf_dev(nic_data),
 	    rtl8139->irq, rtl8139_interrupt_handler, &rtl8139_irq_code);
 
 	RTL8139_IRQ_STRUCT_UNLOCK();
 
-	return rc;
+	return cap;
 }
 
@@ -1321,7 +1322,9 @@
 
 	/* Register interrupt handler */
-	rc = rtl8139_register_int_handler(nic_data);
-	if (rc != EOK)
+	int irq_cap = rtl8139_register_int_handler(nic_data);
+	if (irq_cap < 0) {
+		rc = irq_cap;
 		goto err_pio;
+	}
 
 	fun = ddf_fun_create(nic_get_ddf_dev(nic_data), fun_exposed, "port0");
@@ -1355,5 +1358,5 @@
 	ddf_fun_destroy(fun);
 err_srv:
-	unregister_interrupt_handler(dev, rtl8139->irq);
+	unregister_interrupt_handler(dev, irq_cap);
 err_pio:
 	// rtl8139_pio_disable(dev);
Index: uspace/drv/nic/rtl8169/driver.c
===================================================================
--- uspace/drv/nic/rtl8169/driver.c	(revision d076f1609141fd03fa25c7138c9260c1f6d19dbf)
+++ uspace/drv/nic/rtl8169/driver.c	(revision 300f4c4dd43b87fb910ea1cfccdc3280c2bdd2ca)
@@ -371,8 +371,8 @@
 	rtl8169_irq_code.cmds[2].addr = rtl8169->regs + ISR;
 	rtl8169_irq_code.cmds[3].addr = rtl8169->regs + IMR;
-	int rc = register_interrupt_handler(nic_get_ddf_dev(nic_data),
+	int irq_cap = register_interrupt_handler(nic_get_ddf_dev(nic_data),
 	    rtl8169->irq, rtl8169_irq_handler, &rtl8169_irq_code);
 
-	return rc;
+	return irq_cap;
 }
 
@@ -426,9 +426,9 @@
 		goto err_pio;
 
-	rc = rtl8169_register_int_handler(nic_data);
-	if (rc != EOK) {
+	int irq_cap = rtl8169_register_int_handler(nic_data);
+	if (irq_cap < 0) {
+		rc = irq_cap;
 		ddf_msg(LVL_ERROR, "Failed to register IRQ handler (%d)", rc);
 		goto err_irq;
-
 	}
 
@@ -469,6 +469,6 @@
 err_srv:
 	/* XXX Disconnect from services */
+	unregister_interrupt_handler(dev, irq_cap);
 err_irq:
-	//unregister_interrupt_handler(dev, rtl8169->irq);
 err_pio:
 err_destroy:
Index: uspace/lib/c/generic/async.c
===================================================================
--- uspace/lib/c/generic/async.c	(revision d076f1609141fd03fa25c7138c9260c1f6d19dbf)
+++ uspace/lib/c/generic/async.c	(revision 300f4c4dd43b87fb910ea1cfccdc3280c2bdd2ca)
@@ -1048,14 +1048,14 @@
  *
  * @param inr     IRQ number.
- * @param devno   Device number of the device generating inr.
  * @param handler Notification handler.
  * @param data    Notification handler client data.
  * @param ucode   Top-half pseudocode handler.
  *
- * @return Zero on success or a negative error code.
- *
- */
-int async_irq_subscribe(int inr, int devno,
-    async_notification_handler_t handler, void *data, const irq_code_t *ucode)
+ * @return IRQ capability handle on success.
+ * @return Negative error code.
+ *
+ */
+int async_irq_subscribe(int inr, async_notification_handler_t handler,
+    void *data, const irq_code_t *ucode)
 {
 	notification_t *notification =
@@ -1077,21 +1077,20 @@
 	futex_up(&async_futex);
 	
-	return ipc_irq_subscribe(inr, devno, imethod, ucode);
+	return ipc_irq_subscribe(inr, imethod, ucode);
 }
 
 /** Unsubscribe from IRQ notification.
  *
- * @param inr     IRQ number.
- * @param devno   Device number of the device generating inr.
+ * @param cap     IRQ capability handle. 
  *
  * @return Zero on success or a negative error code.
  *
  */
-int async_irq_unsubscribe(int inr, int devno)
+int async_irq_unsubscribe(int cap)
 {
 	// TODO: Remove entry from hash table
 	//       to avoid memory leak
 	
-	return ipc_irq_unsubscribe(inr, devno);
+	return ipc_irq_unsubscribe(cap);
 }
 
@@ -1384,14 +1383,4 @@
 		async_new_connection(call->in_task_id, in_phone_hash, callid,
 		    call, handler, data);
-		return;
-	}
-	
-	/* Cloned connection */
-	if (IPC_GET_IMETHOD(*call) == IPC_M_CLONE_ESTABLISH) {
-		// TODO: Currently ignores ports altogether
-		
-		/* Open new connection with fibril, etc. */
-		async_new_connection(call->in_task_id, IPC_GET_ARG5(*call),
-		    callid, call, fallback_port_handler, fallback_port_data);
 		return;
 	}
@@ -2111,76 +2100,4 @@
 	
 	return EOK;
-}
-
-/** Wrapper for making IPC_M_CLONE_ESTABLISH calls using the async framework.
- *
- * Ask for a cloned connection to some service.
- *
- * @param mgmt Exchange management style.
- * @param exch Exchange for sending the message.
- *
- * @return New session on success or NULL on error.
- *
- */
-async_sess_t *async_clone_establish(exch_mgmt_t mgmt, async_exch_t *exch)
-{
-	if (exch == NULL) {
-		errno = ENOENT;
-		return NULL;
-	}
-	
-	async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
-	if (sess == NULL) {
-		errno = ENOMEM;
-		return NULL;
-	}
-	
-	ipc_call_t result;
-	
-	amsg_t *msg = amsg_create();
-	if (!msg) {
-		free(sess);
-		errno = ENOMEM;
-		return NULL;
-	}
-	
-	msg->dataptr = &result;
-	msg->wdata.active = true;
-	
-	ipc_call_async_0(exch->phone, IPC_M_CLONE_ESTABLISH, msg,
-	    reply_received);
-	
-	sysarg_t rc;
-	async_wait_for((aid_t) msg, &rc);
-	
-	if (rc != EOK) {
-		errno = rc;
-		free(sess);
-		return NULL;
-	}
-	
-	int phone = (int) IPC_GET_ARG5(result);
-	
-	if (phone < 0) {
-		errno = phone;
-		free(sess);
-		return NULL;
-	}
-	
-	sess->iface = 0;
-	sess->mgmt = mgmt;
-	sess->phone = phone;
-	sess->arg1 = 0;
-	sess->arg2 = 0;
-	sess->arg3 = 0;
-	
-	fibril_mutex_initialize(&sess->remote_state_mtx);
-	sess->remote_state_data = NULL;
-	
-	list_initialize(&sess->exch_list);
-	fibril_mutex_initialize(&sess->mutex);
-	atomic_set(&sess->refcnt, 0);
-	
-	return sess;
 }
 
@@ -3153,64 +3070,4 @@
 }
 
-/** Wrapper for sending an exchange over different exchange for cloning
- *
- * @param exch       Exchange to be used for sending.
- * @param clone_exch Exchange to be cloned.
- *
- */
-int async_exchange_clone(async_exch_t *exch, async_exch_t *clone_exch)
-{
-	return async_req_1_0(exch, IPC_M_CONNECTION_CLONE, clone_exch->phone);
-}
-
-/** Wrapper for receiving the IPC_M_CONNECTION_CLONE calls.
- *
- * If the current call is IPC_M_CONNECTION_CLONE then a new
- * async session is created for the accepted phone.
- *
- * @param mgmt Exchange management style.
- *
- * @return New async session or NULL on failure.
- *
- */
-async_sess_t *async_clone_receive(exch_mgmt_t mgmt)
-{
-	/* Accept the phone */
-	ipc_call_t call;
-	ipc_callid_t callid = async_get_call(&call);
-	int phone = (int) IPC_GET_ARG1(call);
-	
-	if ((IPC_GET_IMETHOD(call) != IPC_M_CONNECTION_CLONE) ||
-	    (phone < 0)) {
-		async_answer_0(callid, EINVAL);
-		return NULL;
-	}
-	
-	async_sess_t *sess = (async_sess_t *) malloc(sizeof(async_sess_t));
-	if (sess == NULL) {
-		async_answer_0(callid, ENOMEM);
-		return NULL;
-	}
-	
-	sess->iface = 0;
-	sess->mgmt = mgmt;
-	sess->phone = phone;
-	sess->arg1 = 0;
-	sess->arg2 = 0;
-	sess->arg3 = 0;
-	
-	fibril_mutex_initialize(&sess->remote_state_mtx);
-	sess->remote_state_data = NULL;
-	
-	list_initialize(&sess->exch_list);
-	fibril_mutex_initialize(&sess->mutex);
-	atomic_set(&sess->refcnt, 0);
-	
-	/* Acknowledge the cloned phone */
-	async_answer_0(callid, EOK);
-	
-	return sess;
-}
-
 /** Wrapper for receiving the IPC_M_CONNECT_TO_ME calls.
  *
Index: uspace/lib/c/generic/ddi.c
===================================================================
--- uspace/lib/c/generic/ddi.c	(revision d076f1609141fd03fa25c7138c9260c1f6d19dbf)
+++ uspace/lib/c/generic/ddi.c	(revision 300f4c4dd43b87fb910ea1cfccdc3280c2bdd2ca)
@@ -50,14 +50,4 @@
 #include "private/libc.h"
 
-
-/** Return unique device number.
- *
- * @return New unique device number.
- *
- */
-int device_assign_devno(void)
-{
-	return __SYSCALL0(SYS_DEVICE_ASSIGN_DEVNO);
-}
 
 /** Map a piece of physical memory to task.
Index: uspace/lib/c/generic/irq.c
===================================================================
--- uspace/lib/c/generic/irq.c	(revision d076f1609141fd03fa25c7138c9260c1f6d19dbf)
+++ uspace/lib/c/generic/irq.c	(revision 300f4c4dd43b87fb910ea1cfccdc3280c2bdd2ca)
@@ -55,32 +55,29 @@
  *
  * @param inr    IRQ number.
- * @param devno  Device number of the device generating inr.
  * @param method Use this method for notifying me.
  * @param ucode  Top-half pseudocode handler.
+ *
+ * @return IRQ capability handle returned by the kernel.
+ * @return Error code returned by the kernel.
+ *
+ */
+int ipc_irq_subscribe(int inr, sysarg_t method, const irq_code_t *ucode)
+{
+	if (ucode == NULL)
+		ucode = &default_ucode;
+	
+	return __SYSCALL3(SYS_IPC_IRQ_SUBSCRIBE, inr, method, (sysarg_t) ucode);
+}
+
+/** Unsubscribe from IRQ notification.
+ *
+ * @param cap   IRQ capability handle.
  *
  * @return Value returned by the kernel.
  *
  */
-int ipc_irq_subscribe(int inr, int devno, sysarg_t method,
-    const irq_code_t *ucode)
+int ipc_irq_unsubscribe(int cap)
 {
-	if (ucode == NULL)
-		ucode = &default_ucode;
-	
-	return __SYSCALL4(SYS_IPC_IRQ_SUBSCRIBE, inr, devno, method,
-	    (sysarg_t) ucode);
-}
-
-/** Unsubscribe from IRQ notification.
- *
- * @param inr   IRQ number.
- * @param devno Device number of the device generating inr.
- *
- * @return Value returned by the kernel.
- *
- */
-int ipc_irq_unsubscribe(int inr, int devno)
-{
-	return __SYSCALL2(SYS_IPC_IRQ_UNSUBSCRIBE, inr, devno);
+	return __SYSCALL1(SYS_IPC_IRQ_UNSUBSCRIBE, cap);
 }
 
Index: uspace/lib/c/include/async.h
===================================================================
--- uspace/lib/c/include/async.h	(revision d076f1609141fd03fa25c7138c9260c1f6d19dbf)
+++ uspace/lib/c/include/async.h	(revision 300f4c4dd43b87fb910ea1cfccdc3280c2bdd2ca)
@@ -166,7 +166,7 @@
     sysarg_t, async_port_handler_t, void *, port_id_t *);
 
-extern int async_irq_subscribe(int, int, async_notification_handler_t, void *,
+extern int async_irq_subscribe(int, async_notification_handler_t, void *,
     const irq_code_t *);
-extern int async_irq_unsubscribe(int, int);
+extern int async_irq_unsubscribe(int);
 
 extern int async_event_subscribe(event_type_t, async_notification_handler_t,
@@ -343,5 +343,4 @@
     sysarg_t *, sysarg_t *);
 
-extern async_sess_t *async_clone_establish(exch_mgmt_t, async_exch_t *);
 extern async_sess_t *async_connect_me_to(exch_mgmt_t, async_exch_t *, sysarg_t,
     sysarg_t, sysarg_t);
@@ -472,6 +471,4 @@
     sysarg_t, sysarg_t, sysarg_t, ipc_call_t *);
 
-extern int async_exchange_clone(async_exch_t *, async_exch_t *);
-extern async_sess_t *async_clone_receive(exch_mgmt_t);
 extern async_sess_t *async_callback_receive(exch_mgmt_t);
 extern async_sess_t *async_callback_receive_start(exch_mgmt_t, ipc_call_t *);
Index: uspace/lib/c/include/ipc/irq.h
===================================================================
--- uspace/lib/c/include/ipc/irq.h	(revision d076f1609141fd03fa25c7138c9260c1f6d19dbf)
+++ uspace/lib/c/include/ipc/irq.h	(revision 300f4c4dd43b87fb910ea1cfccdc3280c2bdd2ca)
@@ -39,6 +39,6 @@
 #include <abi/ddi/irq.h>
 
-extern int ipc_irq_subscribe(int, int, sysarg_t, const irq_code_t *);
-extern int ipc_irq_unsubscribe(int, int);
+extern int ipc_irq_subscribe(int, sysarg_t, const irq_code_t *);
+extern int ipc_irq_unsubscribe(int);
 
 #endif
Index: uspace/lib/drv/generic/interrupt.c
===================================================================
--- uspace/lib/drv/generic/interrupt.c	(revision d076f1609141fd03fa25c7138c9260c1f6d19dbf)
+++ uspace/lib/drv/generic/interrupt.c	(revision 300f4c4dd43b87fb910ea1cfccdc3280c2bdd2ca)
@@ -44,13 +44,13 @@
 
 int register_interrupt_handler(ddf_dev_t *dev, int irq,
-    interrupt_handler_t *handler, const irq_code_t *pseudocode)
+    interrupt_handler_t *handler, const irq_code_t *irq_code)
 {
-	return async_irq_subscribe(irq, dev->handle,
-	    (async_notification_handler_t) handler, dev, pseudocode);
+	return async_irq_subscribe(irq, (async_notification_handler_t) handler,
+	    dev, irq_code);
 }
 
-int unregister_interrupt_handler(ddf_dev_t *dev, int irq)
+int unregister_interrupt_handler(ddf_dev_t *dev, int cap)
 {
-	return async_irq_unsubscribe(irq, dev->handle);
+	return async_irq_unsubscribe(cap);
 }
 
Index: uspace/lib/usbhost/src/ddf_helpers.c
===================================================================
--- uspace/lib/usbhost/src/ddf_helpers.c	(revision d076f1609141fd03fa25c7138c9260c1f6d19dbf)
+++ uspace/lib/usbhost/src/ddf_helpers.c	(revision 300f4c4dd43b87fb910ea1cfccdc3280c2bdd2ca)
@@ -748,5 +748,6 @@
  * @param[in] gen_irq_code IRQ code generator.
  *
- * @return EOK on success or negative error code
+ * @return IRQ capability handle on success.
+ * @return Negative error code.
  */
 int hcd_ddf_setup_interrupts(ddf_dev_t *device,
@@ -770,22 +771,22 @@
 
 	/* Register handler to avoid interrupt lockup */
-	int ret = register_interrupt_handler(device, irq, handler, &irq_code);
+	const int irq_cap = register_interrupt_handler(device, irq, handler,
+	    &irq_code);
 	irq_code_clean(&irq_code);
+	if (irq_cap < 0) {
+		usb_log_error("Failed to register interrupt handler: %s.\n",
+		    str_error(irq_cap));
+		return irq_cap;
+	}
+
+	/* Enable interrupts */
+	int ret = hcd_ddf_enable_interrupts(device);
 	if (ret != EOK) {
 		usb_log_error("Failed to register interrupt handler: %s.\n",
 		    str_error(ret));
-		return ret;
-	}
-
-	/* Enable interrupts */
-	ret = hcd_ddf_enable_interrupts(device);
-	if (ret != EOK) {
-		usb_log_error("Failed to register interrupt handler: %s.\n",
-		    str_error(ret));
-		unregister_interrupt_handler(device, irq);
-		return ret;
-	}
-	assert(irq > 0);
-	return irq;
+		unregister_interrupt_handler(device, irq_cap);
+		return ret;
+	}
+	return irq_cap;
 }
 
@@ -882,7 +883,8 @@
 	interrupt_handler_t *irq_handler =
 	    driver->irq_handler ? driver->irq_handler : ddf_hcd_gen_irq_handler;
-	const int irq = hcd_ddf_setup_interrupts(device, &hw_res, irq_handler,
-	    driver->irq_code_gen);
-	if (!(irq < 0)) {
+	const int irq_cap = hcd_ddf_setup_interrupts(device, &hw_res,
+	    irq_handler, driver->irq_code_gen);
+	bool irqs_enabled = !(irq_cap < 0);
+	if (irqs_enabled) {
 		usb_log_debug("Hw interrupts enabled.\n");
 	}
@@ -899,5 +901,5 @@
 	/* Init hw driver */
 	hcd_t *hcd = dev_to_hcd(device);
-	ret = driver->init(hcd, &hw_res, !(irq < 0));
+	ret = driver->init(hcd, &hw_res, irqs_enabled);
 	hw_res_list_parsed_clean(&hw_res);
 	if (ret != EOK) {
@@ -907,5 +909,5 @@
 
 	/* Need working irq replacement to setup root hub */
-	if ((irq < 0) && hcd->ops.status_hook) {
+	if (!irqs_enabled && hcd->ops.status_hook) {
 		hcd->polling_fibril = fibril_create(interrupt_polling, hcd);
 		if (hcd->polling_fibril == 0) {
@@ -916,5 +918,5 @@
 		fibril_add_ready(hcd->polling_fibril);
 		usb_log_warning("Failed to enable interrupts: %s."
-		    " Falling back to polling.\n", str_error(irq));
+		    " Falling back to polling.\n", str_error(irq_cap));
 	}
 
@@ -930,5 +932,5 @@
 irq_unregister:
 		/* Unregistering non-existent should be ok */
-		unregister_interrupt_handler(device, irq);
+		unregister_interrupt_handler(device, irq_cap);
 		hcd_ddf_clean_hc(device);
 		return ret;
Index: uspace/srv/hid/input/port/msim.c
===================================================================
--- uspace/srv/hid/input/port/msim.c	(revision d076f1609141fd03fa25c7138c9260c1f6d19dbf)
+++ uspace/srv/hid/input/port/msim.c	(revision 300f4c4dd43b87fb910ea1cfccdc3280c2bdd2ca)
@@ -97,6 +97,5 @@
 	msim_ranges[0].base = paddr;
 	msim_cmds[0].addr = (void *) paddr;
-	async_irq_subscribe(inr, device_assign_devno(), msim_irq_handler, NULL,
-	    &msim_kbd);
+	async_irq_subscribe(inr, msim_irq_handler, NULL, &msim_kbd);
 	
 	return 0;
Index: uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c
===================================================================
--- uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c	(revision d076f1609141fd03fa25c7138c9260c1f6d19dbf)
+++ uspace/srv/hid/s3c24xx_ts/s3c24xx_ts.c	(revision 300f4c4dd43b87fb910ea1cfccdc3280c2bdd2ca)
@@ -137,6 +137,5 @@
 	    (void *) ts->paddr, inr);
 
-	async_irq_subscribe(inr, device_assign_devno(), s3c24xx_ts_irq_handler,
-	    NULL, &ts_irq_code);
+	async_irq_subscribe(inr, s3c24xx_ts_irq_handler, NULL, &ts_irq_code);
 
 	s3c24xx_ts_wait_for_int_mode(ts, updn_down);
Index: uspace/srv/hw/bus/cuda_adb/cuda_adb.c
===================================================================
--- uspace/srv/hw/bus/cuda_adb/cuda_adb.c	(revision d076f1609141fd03fa25c7138c9260c1f6d19dbf)
+++ uspace/srv/hw/bus/cuda_adb/cuda_adb.c	(revision 300f4c4dd43b87fb910ea1cfccdc3280c2bdd2ca)
@@ -282,6 +282,5 @@
 	cuda_irq_code.ranges[0].base = (uintptr_t) instance->cuda_physical;
 	cuda_irq_code.cmds[0].addr = (void *) &((cuda_t *) instance->cuda_physical)->ifr;
-	async_irq_subscribe(10, device_assign_devno(), cuda_irq_handler, NULL,
-	    &cuda_irq_code);
+	async_irq_subscribe(10, cuda_irq_handler, NULL, &cuda_irq_code);
 
 	/* Enable SR interrupt. */
Index: uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c
===================================================================
--- uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c	(revision d076f1609141fd03fa25c7138c9260c1f6d19dbf)
+++ uspace/srv/hw/char/s3c24xx_uart/s3c24xx_uart.c	(revision 300f4c4dd43b87fb910ea1cfccdc3280c2bdd2ca)
@@ -193,6 +193,5 @@
 	    (void *) uart->paddr, inr);
 
-	async_irq_subscribe(inr, device_assign_devno(), s3c24xx_uart_irq_handler,
-	    NULL, &uart_irq_code);
+	async_irq_subscribe(inr, s3c24xx_uart_irq_handler, NULL, &uart_irq_code);
 
 	/* Enable FIFO, Tx trigger level: empty, Rx trigger level: 1 byte. */
