Index: uspace/drv/bus/usb/ehci/ehci_bus.c
===================================================================
--- uspace/drv/bus/usb/ehci/ehci_bus.c	(revision 5f0b36652626bacf358059d5959ca96fd2331605)
+++ uspace/drv/bus/usb/ehci/ehci_bus.c	(revision b3573772a2359da2498360d630ee4e92272fd61c)
@@ -163,5 +163,4 @@
 	.endpoint_register = ehci_register_ep,
 	.endpoint_unregister = ehci_unregister_ep,
-	.endpoint_count_bw = bandwidth_count_usb20,
 
 	.batch_create = ehci_create_batch,
@@ -178,5 +177,5 @@
 	bus_t *bus_base = (bus_t *) bus;
 
-	usb2_bus_init(usb2_bus, BANDWIDTH_AVAILABLE_USB20);
+	usb2_bus_init(usb2_bus, &bandwidth_accounting_usb2);
 	bus_base->ops = &ehci_bus_ops;
 
Index: uspace/drv/bus/usb/ohci/ohci_bus.c
===================================================================
--- uspace/drv/bus/usb/ohci/ohci_bus.c	(revision 5f0b36652626bacf358059d5959ca96fd2331605)
+++ uspace/drv/bus/usb/ohci/ohci_bus.c	(revision b3573772a2359da2498360d630ee4e92272fd61c)
@@ -171,5 +171,4 @@
 	.endpoint_register = ohci_register_ep,
 	.endpoint_unregister = ohci_unregister_ep,
-	.endpoint_count_bw = bandwidth_count_usb11,
 
 	.batch_create = ohci_create_batch,
@@ -187,5 +186,5 @@
 	bus_t *bus_base = (bus_t *) bus;
 
-	usb2_bus_init(usb2_bus, BANDWIDTH_AVAILABLE_USB11);
+	usb2_bus_init(usb2_bus, &bandwidth_accounting_usb11);
 	bus_base->ops = &ohci_bus_ops;
 
Index: uspace/drv/bus/usb/uhci/hc.c
===================================================================
--- uspace/drv/bus/usb/uhci/hc.c	(revision 5f0b36652626bacf358059d5959ca96fd2331605)
+++ uspace/drv/bus/usb/uhci/hc.c	(revision b3573772a2359da2498360d630ee4e92272fd61c)
@@ -418,5 +418,4 @@
 	.endpoint_register = endpoint_register,
 	.endpoint_unregister = endpoint_unregister,
-	.endpoint_count_bw = bandwidth_count_usb11,
 
 	.batch_create = create_transfer_batch,
@@ -439,5 +438,5 @@
 	assert(instance);
 
-	usb2_bus_init(&instance->bus, BANDWIDTH_AVAILABLE_USB11);
+	usb2_bus_init(&instance->bus, &bandwidth_accounting_usb11);
 
 	bus_t *bus = (bus_t *) &instance->bus;
Index: uspace/drv/bus/usb/vhc/transfer.c
===================================================================
--- uspace/drv/bus/usb/vhc/transfer.c	(revision 5f0b36652626bacf358059d5959ca96fd2331605)
+++ uspace/drv/bus/usb/vhc/transfer.c	(revision b3573772a2359da2498360d630ee4e92272fd61c)
@@ -166,5 +166,4 @@
 	.parent = &usb2_bus_ops,
 
-	.endpoint_count_bw = bandwidth_count_usb11,
 	.batch_create = batch_create,
 	.batch_schedule = vhc_schedule,
@@ -176,5 +175,5 @@
 	list_initialize(&instance->devices);
 	fibril_mutex_initialize(&instance->guard);
-	usb2_bus_init(&instance->bus, BANDWIDTH_AVAILABLE_USB11);
+	usb2_bus_init(&instance->bus, &bandwidth_accounting_usb11);
 	instance->bus.base.ops = &vhc_bus_ops;
 	return virthub_init(&instance->hub, "root hub");
Index: uspace/lib/usbhost/include/usb/host/bandwidth.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/bandwidth.h	(revision 5f0b36652626bacf358059d5959ca96fd2331605)
+++ uspace/lib/usbhost/include/usb/host/bandwidth.h	(revision b3573772a2359da2498360d630ee4e92272fd61c)
@@ -41,19 +41,15 @@
 #include <stddef.h>
 
-/** Bytes per second in FULL SPEED */
-#define BANDWIDTH_TOTAL_USB11 (12000000 / 8)
-/** 90% of total bandwidth is available for periodic transfers */
-#define BANDWIDTH_AVAILABLE_USB11 ((BANDWIDTH_TOTAL_USB11 * 9) / 10)
-
-/** Number of nanoseconds in one microframe */
-#define BANDWIDTH_TOTAL_USB20 (125000)
-/** 90% of total bandwidth is available for periodic transfers */
-#define BANDWIDTH_AVAILABLE_USB20  ((BANDWIDTH_TOTAL_USB20 * 9) / 10)
-
 typedef struct endpoint endpoint_t;
 
-extern ssize_t bandwidth_count_usb11(endpoint_t *, size_t);
+typedef size_t (*endpoint_count_bw_t)(endpoint_t *);
 
-extern ssize_t bandwidth_count_usb20(endpoint_t *, size_t);
+typedef struct {
+	size_t available_bandwidth;
+	endpoint_count_bw_t count_bw;
+} bandwidth_accounting_t;
+
+extern const bandwidth_accounting_t bandwidth_accounting_usb11;
+extern const bandwidth_accounting_t bandwidth_accounting_usb2;
 
 #endif
Index: uspace/lib/usbhost/include/usb/host/bus.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/bus.h	(revision 5f0b36652626bacf358059d5959ca96fd2331605)
+++ uspace/lib/usbhost/include/usb/host/bus.h	(revision b3573772a2359da2498360d630ee4e92272fd61c)
@@ -120,5 +120,4 @@
 	void (*endpoint_unregister)(endpoint_t *);
 	void (*endpoint_destroy)(endpoint_t *);			/**< Optional */
-	ssize_t (*endpoint_count_bw) (endpoint_t *, size_t);	/**< Optional */
 	usb_transfer_batch_t *(*batch_create)(endpoint_t *);	/**< Optional */
 
Index: uspace/lib/usbhost/include/usb/host/usb2_bus.h
===================================================================
--- uspace/lib/usbhost/include/usb/host/usb2_bus.h	(revision 5f0b36652626bacf358059d5959ca96fd2331605)
+++ uspace/lib/usbhost/include/usb/host/usb2_bus.h	(revision b3573772a2359da2498360d630ee4e92272fd61c)
@@ -42,4 +42,5 @@
 
 #include <usb/host/bus.h>
+#include <usb/host/bandwidth.h>
 
 typedef struct usb2_bus usb2_bus_t;
@@ -57,9 +58,12 @@
 	/** Size of the bandwidth pool */
 	size_t free_bw;
+
+	/* Configured bandwidth accounting */
+	const bandwidth_accounting_t *bw_accounting;
 } usb2_bus_t;
 
 extern const bus_ops_t usb2_bus_ops;
 
-extern void usb2_bus_init(usb2_bus_t *, size_t);
+extern void usb2_bus_init(usb2_bus_t *, const bandwidth_accounting_t *);
 
 #endif
Index: uspace/lib/usbhost/src/bandwidth.c
===================================================================
--- uspace/lib/usbhost/src/bandwidth.c	(revision 5f0b36652626bacf358059d5959ca96fd2331605)
+++ uspace/lib/usbhost/src/bandwidth.c	(revision b3573772a2359da2498360d630ee4e92272fd61c)
@@ -42,12 +42,16 @@
 #include "bandwidth.h"
 
+/** Bytes per second in FULL SPEED */
+#define BANDWIDTH_TOTAL_USB11 (12000000 / 8)
+/** 90% of total bandwidth is available for periodic transfers */
+#define BANDWIDTH_AVAILABLE_USB11 ((BANDWIDTH_TOTAL_USB11 * 9) / 10)
+
 /**
  * Calculate bandwidth that needs to be reserved for communication with EP.
  * Calculation follows USB 1.1 specification.
- * @param ep Registered endpoint
- * @param size Number of bytes to transfer.
- * @param max_packet_size Maximum bytes in one packet.
+ *
+ * @param ep An endpoint for which the bandwidth is to be counted
  */
-ssize_t bandwidth_count_usb11(endpoint_t *ep, size_t size)
+static size_t bandwidth_count_usb11(endpoint_t *ep)
 {
 	assert(ep);
@@ -63,7 +67,6 @@
 
 	const size_t max_packet_size = ep->max_packet_size;
+	const size_t packet_count = ep->packets_per_uframe;
 
-	const unsigned packet_count =
-	    (size + max_packet_size - 1) / max_packet_size;
 	/* TODO: It may be that ISO and INT transfers use only one packet per
 	 * transaction, but I did not find text in USB spec to confirm this */
@@ -96,18 +99,28 @@
 }
 
-/** 
+const bandwidth_accounting_t bandwidth_accounting_usb11 = {
+	.available_bandwidth = BANDWIDTH_AVAILABLE_USB11,
+	.count_bw = &bandwidth_count_usb11,
+};
+
+/** Number of nanoseconds in one microframe */
+#define BANDWIDTH_TOTAL_USB2 (125000)
+/** 90% of total bandwidth is available for periodic transfers */
+#define BANDWIDTH_AVAILABLE_USB2  ((BANDWIDTH_TOTAL_USB2 * 9) / 10)
+
+/**
  * Calculate bandwidth that needs to be reserved for communication with EP.
  * Calculation follows USB 2.0 specification, chapter 5.11.3.
  *
- * @param speed Device's speed.
- * @param type Type of the transfer.
- * @param size Number of byte to transfer.
- * @param max_packet_size Maximum bytes in one packet.
+ * FIXME: Interrupt transfers shall be probably divided by their polling interval.
+ *
+ * @param ep An endpoint for which the bandwidth is to be counted
  * @return Number of nanoseconds transaction with @c size bytes payload will
  *         take.
  */
-ssize_t bandwidth_count_usb20(endpoint_t *ep, size_t size)
+static size_t bandwidth_count_usb2(endpoint_t *ep)
 {
 	assert(ep);
+	assert(ep->device);
 
 	const usb_transfer_type_t type = ep->transfer_type;
@@ -124,5 +137,5 @@
 
 	// Approx. Floor(3.167 + BitStuffTime(Data_bc))
-	const size_t base_time = (size * 8 + 19) / 6;
+	const size_t base_time = (ep->max_transfer_size * 8 + 19) / 6;
 
 	switch (ep->device->speed) {
@@ -152,2 +165,7 @@
 	}
 }
+
+const bandwidth_accounting_t bandwidth_accounting_usb2 = {
+	.available_bandwidth = BANDWIDTH_AVAILABLE_USB2,
+	.count_bw = &bandwidth_count_usb2,
+};
Index: uspace/lib/usbhost/src/usb2_bus.c
===================================================================
--- uspace/lib/usbhost/src/usb2_bus.c	(revision 5f0b36652626bacf358059d5959ca96fd2331605)
+++ uspace/lib/usbhost/src/usb2_bus.c	(revision b3573772a2359da2498360d630ee4e92272fd61c)
@@ -219,10 +219,7 @@
 	assert(ep);
 
-	bus_t *bus = ep->device->bus;
-	const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, endpoint_count_bw);
-	if (!ops)
-		return 0;
-
-	return ops->endpoint_count_bw(ep, ep->max_transfer_size);
+	usb2_bus_t *bus = bus_to_usb2_bus(ep->device->bus);
+
+	return bus->bw_accounting->count_bw(ep);
 }
 
@@ -269,12 +266,14 @@
  * @param available_bandwidth Size of the bandwidth pool.
  */
-void usb2_bus_init(usb2_bus_t *bus, size_t available_bandwidth)
+void usb2_bus_init(usb2_bus_t *bus, const bandwidth_accounting_t *bw_accounting)
 {
 	assert(bus);
+	assert(bw_accounting);
 
 	bus_init(&bus->base, sizeof(device_t));
 	bus->base.ops = &usb2_bus_ops;
 
-	bus->free_bw = available_bandwidth;
+	bus->bw_accounting = bw_accounting;
+	bus->free_bw = bw_accounting->available_bandwidth;
 
 	/*
