Index: uspace/lib/usbhost/include/usb/host/bus.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/bus.h	(revision 6832245517c6257fe330523cebfec7b916fdb0bf)
+++ uspace/lib/usbhost/include/usb/host/bus.h	(revision 85bf12bae025fd54ef10740528488cbe5849d969)
@@ -43,11 +43,11 @@
 #define LIBUSBHOST_HOST_BUS_H
 
-#include <usb/usb.h>
-#include <usb/request.h>
-#include <usb/host/hcd.h>
-
 #include <assert.h>
 #include <fibril_synch.h>
 #include <stdbool.h>
+#include <usb/host/hcd.h>
+#include <usb/request.h>
+#include <usb/usb.h>
+#include <usbhc_iface.h>
 
 typedef struct hcd hcd_t;
@@ -94,4 +94,6 @@
 
 	/* Global operations on the bus */
+	void (*interrupt)(bus_t *, uint32_t);
+	int (*status)(bus_t *, uint32_t *);
 	int (*reserve_default_address)(bus_t *, usb_speed_t);
 	int (*release_default_address)(bus_t *);
@@ -116,5 +118,6 @@
 
 	/* Operations on batch */
-	void (*batch_destroy)(usb_transfer_batch_t *);	/**< Optional */
+	void (*batch_destroy)(usb_transfer_batch_t *);		/**< Optional */
+	int (*batch_schedule)(usb_transfer_batch_t *);
 };
 
@@ -129,7 +132,5 @@
 	fibril_mutex_t guard;
 
-	/* TODO: get rid of this one. */
-	hcd_t *hcd;
-
+	/* Size of the device_t extended structure */
 	size_t device_size;
 
@@ -140,5 +141,5 @@
 } bus_t;
 
-void bus_init(bus_t *, hcd_t *, size_t);
+void bus_init(bus_t *, size_t);
 int bus_device_init(device_t *, bus_t *);
 
@@ -150,4 +151,12 @@
 int bus_device_online(device_t *);
 int bus_device_offline(device_t *);
+
+int bus_device_send_batch(device_t *, usb_target_t,
+    usb_direction_t direction, char *, size_t, uint64_t,
+    usbhc_iface_transfer_callback_t, void *, const char *);
+
+ssize_t bus_device_send_batch_sync(device_t *, usb_target_t,
+    usb_direction_t direction, char *, size_t, uint64_t,
+    const char *);
 
 int bus_endpoint_add(device_t *, const usb_endpoint_desc_t *, endpoint_t **);
Index: uspace/lib/usbhost/include/usb/host/ddf_helpers.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/ddf_helpers.h	(revision 6832245517c6257fe330523cebfec7b916fdb0bf)
+++ uspace/lib/usbhost/include/usb/host/ddf_helpers.h	(revision 85bf12bae025fd54ef10740528488cbe5849d969)
@@ -39,61 +39,22 @@
 #include <ddf/driver.h>
 #include <ddf/interrupt.h>
-#include <device/hw_res_parsed.h>
 #include <usb/usb.h>
 
 #include <usb/host/hcd.h>
 
-typedef int (*driver_init_t)(hcd_t *, const hw_res_list_parsed_t *, ddf_dev_t *);
-typedef int (*irq_code_gen_t)(irq_code_t *, hcd_t *, const hw_res_list_parsed_t *);
-typedef int (*claim_t)(hcd_t *, ddf_dev_t *);
-typedef int (*driver_start_t)(hcd_t *, bool irq);
-typedef int (*setup_root_hub_t)(hcd_t *, ddf_dev_t *);
+int hcd_ddf_setup_hc(ddf_dev_t *, size_t);
+void hcd_ddf_clean_hc(hc_device_t *);
 
-typedef void (*driver_stop_t)(hcd_t *);
-typedef void (*driver_fini_t)(hcd_t *);
+int hcd_setup_virtual_root_hub(hc_device_t *);
 
-/**
- * All callbacks are optional.
- */
-typedef struct {
-	hcd_ops_t ops;
-	const char *name;
+device_t *hcd_ddf_fun_create(hc_device_t *);
+void hcd_ddf_fun_destroy(device_t *);
 
-	interrupt_handler_t *irq_handler;  /**< Handler of IRQ. Do have generic implementation. */
+int hcd_device_explore(device_t *);
 
-	/* Initialization sequence: */
-	driver_init_t init;                /**< Initialize internal structures, memory */
-	claim_t claim;                     /**< Claim device from BIOS */
-	irq_code_gen_t irq_code_gen;       /**< Generate IRQ handling code */
-	driver_start_t start;              /**< Start the HC */
-	setup_root_hub_t setup_root_hub;   /**< Setup the root hub */
+int hcd_ddf_enable_interrupt(hc_device_t *hcd, int);
+int hcd_ddf_get_registers(hc_device_t *hcd, hw_res_list_parsed_t *hw_res);
 
-	/* Destruction sequence: */
-	driver_stop_t stop;                /**< Stop the HC (counterpart of start) */
-	driver_fini_t fini;                /**< Destroy internal structures (counterpart of init) */
-} ddf_hc_driver_t;
-
-int hcd_ddf_add_hc(ddf_dev_t *device, const ddf_hc_driver_t *driver);
-
-int hcd_ddf_setup_hc(ddf_dev_t *device);
-void hcd_ddf_clean_hc(ddf_dev_t *device);
-
-int hcd_setup_virtual_root_hub(hcd_t *, ddf_dev_t *);
-
-device_t *hcd_ddf_device_create(ddf_dev_t *, bus_t *);
-void hcd_ddf_device_destroy(device_t *);
-int hcd_ddf_device_explore(device_t *);
-int hcd_ddf_device_online(ddf_fun_t *);
-int hcd_ddf_device_offline(ddf_fun_t *);
-
-hcd_t *dev_to_hcd(ddf_dev_t *dev);
-
-int hcd_ddf_enable_interrupt(ddf_dev_t *device, int);
-int hcd_ddf_get_registers(ddf_dev_t *device, hw_res_list_parsed_t *hw_res);
-int hcd_ddf_setup_interrupts(ddf_dev_t *device,
-    const hw_res_list_parsed_t *hw_res,
-    interrupt_handler_t handler,
-    irq_code_gen_t gen_irq_code);
-void ddf_hcd_gen_irq_handler(ipc_callid_t iid, ipc_call_t *call, ddf_dev_t *dev);
+void hcd_ddf_gen_irq_handler(ipc_callid_t iid, ipc_call_t *call, ddf_dev_t *dev);
 
 #endif
Index: uspace/lib/usbhost/include/usb/host/endpoint.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/endpoint.h	(revision 6832245517c6257fe330523cebfec7b916fdb0bf)
+++ uspace/lib/usbhost/include/usb/host/endpoint.h	(revision 85bf12bae025fd54ef10740528488cbe5849d969)
@@ -109,4 +109,8 @@
 ssize_t endpoint_count_bw(endpoint_t *, size_t);
 
+int endpoint_send_batch(endpoint_t *, usb_target_t, usb_direction_t,
+    char *, size_t, uint64_t, usbhc_iface_transfer_callback_t, void *,
+    const char *);
+
 static inline bus_t *endpoint_get_bus(endpoint_t *ep)
 {
Index: uspace/lib/usbhost/include/usb/host/hcd.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/hcd.h	(revision 6832245517c6257fe330523cebfec7b916fdb0bf)
+++ uspace/lib/usbhost/include/usb/host/hcd.h	(revision 85bf12bae025fd54ef10740528488cbe5849d969)
@@ -37,75 +37,82 @@
 #define LIBUSBHOST_HOST_HCD_H
 
-#include <assert.h>
-#include <mem.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <usb/usb.h>
-#include <usbhc_iface.h>
+#include <ddf/driver.h>
+#include <usb/request.h>
 
-typedef struct hcd hcd_t;
+typedef struct hw_resource_list_parsed hw_res_list_parsed_t;
 typedef struct bus bus_t;
 typedef struct device device_t;
-typedef struct usb_transfer_batch usb_transfer_batch_t;
 
-typedef int (*schedule_hook_t)(hcd_t *, usb_transfer_batch_t *);
-typedef void (*interrupt_hook_t)(hcd_t *, uint32_t);
-typedef int (*status_hook_t)(hcd_t *, uint32_t *);
+/* Treat this header as read-only in driver code.
+ * It could be opaque, but why to complicate matters.
+ */
+typedef struct hc_device {
+	/* Bus instance */
+	bus_t *bus;
 
-typedef struct {
-	/** Transfer scheduling, implement in device driver. */
-	schedule_hook_t schedule;
-	/** Hook to be called on device interrupt, passes ARG1 */
-	interrupt_hook_t irq_hook;
-	/** Periodic polling hook */
-	status_hook_t status_hook;
-} hcd_ops_t;
+	/* Managed DDF device */
+	ddf_dev_t *ddf_dev;
 
-/** Generic host controller driver structure. */
-struct hcd {
-	/** Endpoint manager. */
-	bus_t *bus;
+	/* Control function */
+	ddf_fun_t *ctl_fun;
+
+	/* Result of enabling HW IRQs */
+	int irq_cap;
 
 	/** Interrupt replacement fibril */
 	fid_t polling_fibril;
 
-	/** Driver implementation */
-	hcd_ops_t ops;
+	/* This structure is meant to be extended by driver code. */
+} hc_device_t;
 
-	/** Device specific driver data. */
-	void * driver_data;
-};
+typedef struct hc_driver {
+	const char *name;
 
-extern void hcd_init(hcd_t *);
+	/** Size of the device data to be allocated, and passed as the
+	 * hc_device_t. */
+	size_t hc_device_size;
 
-static inline void hcd_set_implementation(hcd_t *hcd, void *data,
-    const hcd_ops_t *ops, bus_t *bus)
-{
-	assert(hcd);
-	if (ops) {
-		hcd->driver_data = data;
-		hcd->ops = *ops;
-		hcd->bus = bus;
-	} else {
-		memset(&hcd->ops, 0, sizeof(hcd->ops));
-	}
+	/** Initialize device structures. */
+	int (*hc_add)(hc_device_t *, const hw_res_list_parsed_t *);
+
+	/** Generate IRQ code to handle interrupts. */
+	int (*irq_code_gen)(irq_code_t *, hc_device_t *, const hw_res_list_parsed_t *);
+
+	/** Claim device from BIOS. */
+	int (*claim)(hc_device_t *);
+
+	/** Start the host controller. */
+	int (*start)(hc_device_t *);
+
+	/** Setup the virtual roothub. */
+	int (*setup_root_hub)(hc_device_t *);
+
+	/** Stop the host controller (after start has been called) */
+	int (*stop)(hc_device_t *);
+
+	/** HC was asked to be removed (after hc_add has been called) */
+	int (*hc_remove)(hc_device_t *);
+
+	/** HC is gone. */
+	int (*hc_gone)(hc_device_t *);
+} hc_driver_t;
+
+/* Drivers should call this before leaving hc_add */
+static inline void hc_device_setup(hc_device_t *hcd, bus_t *bus) {
+	hcd->bus = bus;
 }
 
-static inline void * hcd_get_driver_data(hcd_t *hcd)
+static inline hc_device_t *dev_to_hcd(ddf_dev_t *dev)
 {
-	assert(hcd);
-	return hcd->driver_data;
+	return ddf_dev_data_get(dev);
 }
 
-extern int hcd_get_ep0_max_packet_size(uint16_t *, hcd_t *, device_t *);
+int hc_driver_main(const hc_driver_t *);
+
+/* TODO: These are a kind of utility functions, they should probably go
+ * somewhere else.
+ */
+extern int hcd_get_ep0_max_packet_size(uint16_t *, bus_t *, device_t *);
 extern void hcd_setup_device_tt(device_t *);
-
-extern int hcd_send_batch(hcd_t *, device_t *, usb_target_t,
-    usb_direction_t direction, char *, size_t, uint64_t,
-    usbhc_iface_transfer_callback_t, void *, const char *);
-
-extern ssize_t hcd_send_batch_sync(hcd_t *, device_t *, usb_target_t,
-    usb_direction_t direction, char *, size_t, uint64_t,
-    const char *);
 
 /** How many toggles need to be reset */
@@ -116,4 +123,7 @@
 } toggle_reset_mode_t;
 
+extern toggle_reset_mode_t hcd_get_request_toggle_reset_mode(
+    const usb_device_request_setup_packet_t *request);
+
 #endif
 
Index: uspace/lib/usbhost/include/usb/host/usb2_bus.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/usb2_bus.h	(revision 6832245517c6257fe330523cebfec7b916fdb0bf)
+++ uspace/lib/usbhost/include/usb/host/usb2_bus.h	(revision 85bf12bae025fd54ef10740528488cbe5849d969)
@@ -66,5 +66,5 @@
 extern const bus_ops_t usb2_bus_ops;
 
-extern int usb2_bus_init(usb2_bus_t *, hcd_t *, size_t);
+extern int usb2_bus_init(usb2_bus_t *, size_t);
 
 #endif
