core: update usbi_dbg to take the context as an argument

This commit fixes a performance issue caused by the disconnection of the first context
allocated from the default context. usbi_dbg now takes the explicit context instead of
relying on the default context (which may not exist) in most cases. All call sites have
been updated to pass the context or explicitly pass NULL if the context is not
available. We should actively discourage using NULL as the context in the future and
patch all call sites to always pass the context.

Fixes #951

Signed-off-by: Nathan Hjelm <hjelmn@google.com>
diff --git a/libusb/core.c b/libusb/core.c
index 0cdc960..4ec410b 100644
--- a/libusb/core.c
+++ b/libusb/core.c
@@ -676,7 +676,7 @@
 	}
 
 	/* exceeded capacity, need to grow */
-	usbi_dbg("need to increase capacity");
+	usbi_dbg(DEVICE_CTX(dev), "need to increase capacity");
 	capacity = discdevs->capacity + DISCOVERED_DEVICES_SIZE_STEP;
 	/* can't use usbi_reallocf here because in failure cases it would
 	 * free the existing discdevs without unreferencing its devices. */
@@ -762,7 +762,7 @@
 		usbi_err(DEVICE_CTX(dev), "too many configurations");
 		return LIBUSB_ERROR_IO;
 	} else if (0 == num_configurations) {
-		usbi_dbg("zero configurations, maybe an unauthorized device");
+		usbi_dbg(DEVICE_CTX(dev), "zero configurations, maybe an unauthorized device");
 	}
 
 	return 0;
@@ -817,7 +817,7 @@
 	int r = 0;
 	ssize_t i, len;
 
-	usbi_dbg(" ");
+	usbi_dbg(ctx, " ");
 
 	if (!discdevs)
 		return LIBUSB_ERROR_NO_MEM;
@@ -1184,7 +1184,7 @@
 	assert(refcnt >= 0);
 
 	if (refcnt == 0) {
-		usbi_dbg("destroy device %d.%d", dev->bus_number, dev->device_address);
+		usbi_dbg(DEVICE_CTX(dev), "destroy device %d.%d", dev->bus_number, dev->device_address);
 
 		libusb_unref_device(dev->parent_dev);
 
@@ -1242,7 +1242,7 @@
 	size_t priv_size = usbi_backend.device_handle_priv_size;
 	int r;
 
-	usbi_dbg("wrap_sys_device 0x%" PRIxPTR, (uintptr_t)sys_dev);
+	usbi_dbg(ctx, "wrap_sys_device 0x%" PRIxPTR, (uintptr_t)sys_dev);
 
 	ctx = usbi_get_context(ctx);
 
@@ -1257,7 +1257,7 @@
 
 	r = usbi_backend.wrap_sys_device(ctx, _dev_handle, sys_dev);
 	if (r < 0) {
-		usbi_dbg("wrap_sys_device 0x%" PRIxPTR " returns %d", (uintptr_t)sys_dev, r);
+		usbi_dbg(ctx, "wrap_sys_device 0x%" PRIxPTR " returns %d", (uintptr_t)sys_dev, r);
 		usbi_mutex_destroy(&_dev_handle->lock);
 		free(_dev_handle);
 		return r;
@@ -1298,7 +1298,7 @@
 	size_t priv_size = usbi_backend.device_handle_priv_size;
 	int r;
 
-	usbi_dbg("open %d.%d", dev->bus_number, dev->device_address);
+	usbi_dbg(DEVICE_CTX(dev), "open %d.%d", dev->bus_number, dev->device_address);
 
 	if (!usbi_atomic_load(&dev->attached))
 		return LIBUSB_ERROR_NO_DEVICE;
@@ -1313,7 +1313,7 @@
 
 	r = usbi_backend.open(_dev_handle);
 	if (r < 0) {
-		usbi_dbg("open %d.%d returns %d", dev->bus_number, dev->device_address, r);
+		usbi_dbg(DEVICE_CTX(dev), "open %d.%d returns %d", dev->bus_number, dev->device_address, r);
 		libusb_unref_device(dev);
 		usbi_mutex_destroy(&_dev_handle->lock);
 		free(_dev_handle);
@@ -1419,7 +1419,7 @@
 		 * just making sure that we don't attempt to process the transfer after
 		 * the device handle is invalid
 		 */
-		usbi_dbg("Removed transfer %p from the in-flight list because device handle %p closed",
+		usbi_dbg(ctx, "Removed transfer %p from the in-flight list because device handle %p closed",
 			 transfer, dev_handle);
 	}
 	usbi_mutex_unlock(&ctx->flying_transfers_lock);
@@ -1453,9 +1453,9 @@
 
 	if (!dev_handle)
 		return;
-	usbi_dbg(" ");
-
 	ctx = HANDLE_CTX(dev_handle);
+	usbi_dbg(ctx, " ");
+
 	handling_events = usbi_handling_events(ctx);
 
 	/* Similarly to libusb_open(), we want to interrupt all event handlers
@@ -1537,27 +1537,28 @@
 {
 	int r = LIBUSB_ERROR_NOT_SUPPORTED;
 	uint8_t tmp = 0;
+	struct libusb_context *ctx = HANDLE_CTX(dev_handle);
 
-	usbi_dbg(" ");
+	usbi_dbg(ctx, " ");
 	if (usbi_backend.get_configuration)
 		r = usbi_backend.get_configuration(dev_handle, &tmp);
 
 	if (r == LIBUSB_ERROR_NOT_SUPPORTED) {
-		usbi_dbg("falling back to control message");
+		usbi_dbg(ctx, "falling back to control message");
 		r = libusb_control_transfer(dev_handle, LIBUSB_ENDPOINT_IN,
 			LIBUSB_REQUEST_GET_CONFIGURATION, 0, 0, &tmp, 1, 1000);
 		if (r == 1) {
 			r = 0;
 		} else if (r == 0) {
-			usbi_err(HANDLE_CTX(dev_handle), "zero bytes returned in ctrl transfer?");
+			usbi_err(ctx, "zero bytes returned in ctrl transfer?");
 			r = LIBUSB_ERROR_IO;
 		} else {
-			usbi_dbg("control failed, error %d", r);
+			usbi_dbg(ctx, "control failed, error %d", r);
 		}
 	}
 
 	if (r == 0) {
-		usbi_dbg("active config %u", tmp);
+		usbi_dbg(ctx, "active config %u", tmp);
 		*config = (int)tmp;
 	}
 
@@ -1621,7 +1622,7 @@
 int API_EXPORTED libusb_set_configuration(libusb_device_handle *dev_handle,
 	int configuration)
 {
-	usbi_dbg("configuration %d", configuration);
+	usbi_dbg(HANDLE_CTX(dev_handle), "configuration %d", configuration);
 	if (configuration < -1 || configuration > (int)UINT8_MAX)
 		return LIBUSB_ERROR_INVALID_PARAM;
 	return usbi_backend.set_configuration(dev_handle, configuration);
@@ -1660,7 +1661,7 @@
 {
 	int r = 0;
 
-	usbi_dbg("interface %d", interface_number);
+	usbi_dbg(HANDLE_CTX(dev_handle), "interface %d", interface_number);
 	if (interface_number < 0 || interface_number >= USB_MAXINTERFACES)
 		return LIBUSB_ERROR_INVALID_PARAM;
 
@@ -1704,7 +1705,7 @@
 {
 	int r;
 
-	usbi_dbg("interface %d", interface_number);
+	usbi_dbg(HANDLE_CTX(dev_handle), "interface %d", interface_number);
 	if (interface_number < 0 || interface_number >= USB_MAXINTERFACES)
 		return LIBUSB_ERROR_INVALID_PARAM;
 
@@ -1747,7 +1748,7 @@
 int API_EXPORTED libusb_set_interface_alt_setting(libusb_device_handle *dev_handle,
 	int interface_number, int alternate_setting)
 {
-	usbi_dbg("interface %d altsetting %d",
+	usbi_dbg(HANDLE_CTX(dev_handle), "interface %d altsetting %d",
 		interface_number, alternate_setting);
 	if (interface_number < 0 || interface_number >= USB_MAXINTERFACES)
 		return LIBUSB_ERROR_INVALID_PARAM;
@@ -1789,7 +1790,7 @@
 int API_EXPORTED libusb_clear_halt(libusb_device_handle *dev_handle,
 	unsigned char endpoint)
 {
-	usbi_dbg("endpoint 0x%x", endpoint);
+	usbi_dbg(HANDLE_CTX(dev_handle), "endpoint 0x%x", endpoint);
 	if (!usbi_atomic_load(&dev_handle->dev->attached))
 		return LIBUSB_ERROR_NO_DEVICE;
 
@@ -1817,7 +1818,7 @@
  */
 int API_EXPORTED libusb_reset_device(libusb_device_handle *dev_handle)
 {
-	usbi_dbg(" ");
+	usbi_dbg(HANDLE_CTX(dev_handle), " ");
 	if (!usbi_atomic_load(&dev_handle->dev->attached))
 		return LIBUSB_ERROR_NO_DEVICE;
 
@@ -1851,7 +1852,7 @@
 int API_EXPORTED libusb_alloc_streams(libusb_device_handle *dev_handle,
 	uint32_t num_streams, unsigned char *endpoints, int num_endpoints)
 {
-	usbi_dbg("streams %u eps %d", (unsigned)num_streams, num_endpoints);
+	usbi_dbg(HANDLE_CTX(dev_handle), "streams %u eps %d", (unsigned)num_streams, num_endpoints);
 
 	if (!num_streams || !endpoints || num_endpoints <= 0)
 		return LIBUSB_ERROR_INVALID_PARAM;
@@ -1881,7 +1882,7 @@
 int API_EXPORTED libusb_free_streams(libusb_device_handle *dev_handle,
 	unsigned char *endpoints, int num_endpoints)
 {
-	usbi_dbg("eps %d", num_endpoints);
+	usbi_dbg(HANDLE_CTX(dev_handle), "eps %d", num_endpoints);
 
 	if (!endpoints || num_endpoints <= 0)
 		return LIBUSB_ERROR_INVALID_PARAM;
@@ -1970,7 +1971,7 @@
 int API_EXPORTED libusb_kernel_driver_active(libusb_device_handle *dev_handle,
 	int interface_number)
 {
-	usbi_dbg("interface %d", interface_number);
+	usbi_dbg(HANDLE_CTX(dev_handle), "interface %d", interface_number);
 
 	if (interface_number < 0 || interface_number >= USB_MAXINTERFACES)
 		return LIBUSB_ERROR_INVALID_PARAM;
@@ -2008,7 +2009,7 @@
 int API_EXPORTED libusb_detach_kernel_driver(libusb_device_handle *dev_handle,
 	int interface_number)
 {
-	usbi_dbg("interface %d", interface_number);
+	usbi_dbg(HANDLE_CTX(dev_handle), "interface %d", interface_number);
 
 	if (interface_number < 0 || interface_number >= USB_MAXINTERFACES)
 		return LIBUSB_ERROR_INVALID_PARAM;
@@ -2044,7 +2045,7 @@
 int API_EXPORTED libusb_attach_kernel_driver(libusb_device_handle *dev_handle,
 	int interface_number)
 {
-	usbi_dbg("interface %d", interface_number);
+	usbi_dbg(HANDLE_CTX(dev_handle), "interface %d", interface_number);
 
 	if (interface_number < 0 || interface_number >= USB_MAXINTERFACES)
 		return LIBUSB_ERROR_INVALID_PARAM;
@@ -2279,7 +2280,7 @@
 	usbi_mutex_static_lock(&default_context_lock);
 
 	if (!ctx && usbi_default_context) {
-		usbi_dbg("reusing default context");
+		usbi_dbg(usbi_default_context, "reusing default context");
 		default_context_refcnt++;
 		usbi_mutex_static_unlock(&default_context_lock);
 		return 0;
@@ -2311,10 +2312,10 @@
 	if (!ctx) {
 		usbi_default_context = _ctx;
 		default_context_refcnt = 1;
-		usbi_dbg("created default context");
+		usbi_dbg(usbi_default_context, "created default context");
 	}
 
-	usbi_dbg("libusb v%u.%u.%u.%u%s", libusb_version_internal.major, libusb_version_internal.minor,
+	usbi_dbg(_ctx, "libusb v%u.%u.%u.%u%s", libusb_version_internal.major, libusb_version_internal.minor,
 		libusb_version_internal.micro, libusb_version_internal.nano, libusb_version_internal.rc);
 
 	usbi_mutex_init(&_ctx->usb_devs_lock);
@@ -2396,21 +2397,21 @@
 	 * if we're the last user */
 	if (!ctx) {
 		if (!usbi_default_context) {
-			usbi_dbg("no default context, not initialized?");
+			usbi_dbg(ctx, "no default context, not initialized?");
 			usbi_mutex_static_unlock(&default_context_lock);
 			return;
 		}
 
 		if (--default_context_refcnt > 0) {
-			usbi_dbg("not destroying default context");
+			usbi_dbg(ctx, "not destroying default context");
 			usbi_mutex_static_unlock(&default_context_lock);
 			return;
 		}
 
-		usbi_dbg("destroying default context");
+		usbi_dbg(ctx, "destroying default context");
 		_ctx = usbi_default_context;
 	} else {
-		usbi_dbg(" ");
+		usbi_dbg(ctx, " ");
 		_ctx = ctx;
 	}
 
diff --git a/libusb/descriptor.c b/libusb/descriptor.c
index ecd9441..10e0570 100644
--- a/libusb/descriptor.c
+++ b/libusb/descriptor.c
@@ -140,7 +140,7 @@
 		    header->bDescriptorType == LIBUSB_DT_DEVICE)
 			break;
 
-		usbi_dbg("skipping descriptor 0x%x", header->bDescriptorType);
+		usbi_dbg(ctx, "skipping descriptor 0x%x", header->bDescriptorType);
 		buffer += header->bLength;
 		size -= header->bLength;
 		parsed += header->bLength;
@@ -414,7 +414,7 @@
 			    header->bDescriptorType == LIBUSB_DT_DEVICE)
 				break;
 
-			usbi_dbg("skipping descriptor 0x%x", header->bDescriptorType);
+			usbi_dbg(ctx, "skipping descriptor 0x%x", header->bDescriptorType);
 			buffer += header->bLength;
 			size -= header->bLength;
 		}
@@ -531,7 +531,7 @@
 int API_EXPORTED libusb_get_device_descriptor(libusb_device *dev,
 	struct libusb_device_descriptor *desc)
 {
-	usbi_dbg(" ");
+	usbi_dbg(DEVICE_CTX(dev), " ");
 	static_assert(sizeof(dev->device_descriptor) == LIBUSB_DT_DEVICE_SIZE,
 		      "struct libusb_device_descriptor is not expected size");
 	*desc = dev->device_descriptor;
@@ -601,7 +601,7 @@
 	uint8_t *buf;
 	int r;
 
-	usbi_dbg("index %u", config_index);
+	usbi_dbg(DEVICE_CTX(dev), "index %u", config_index);
 	if (config_index >= dev->device_descriptor.bNumConfigurations)
 		return LIBUSB_ERROR_NOT_FOUND;
 
@@ -656,7 +656,7 @@
 		return raw_desc_to_config(DEVICE_CTX(dev), buf, r, config);
 	}
 
-	usbi_dbg("value %u", bConfigurationValue);
+	usbi_dbg(DEVICE_CTX(dev), "value %u", bConfigurationValue);
 	for (idx = 0; idx < dev->device_descriptor.bNumConfigurations; idx++) {
 		union usbi_config_desc_buf _config;
 
@@ -850,23 +850,24 @@
 	uint16_t bos_len;
 	uint8_t *bos_data;
 	int r;
+	struct libusb_context *ctx = HANDLE_CTX(dev_handle);
 
 	/* Read the BOS. This generates 2 requests on the bus,
 	 * one for the header, and one for the full BOS */
 	r = libusb_get_descriptor(dev_handle, LIBUSB_DT_BOS, 0, _bos.buf, sizeof(_bos.buf));
 	if (r < 0) {
 		if (r != LIBUSB_ERROR_PIPE)
-			usbi_err(HANDLE_CTX(dev_handle), "failed to read BOS (%d)", r);
+			usbi_err(ctx, "failed to read BOS (%d)", r);
 		return r;
 	}
 	if (r < LIBUSB_DT_BOS_SIZE) {
-		usbi_err(HANDLE_CTX(dev_handle), "short BOS read %d/%d",
+		usbi_err(ctx, "short BOS read %d/%d",
 			 r, LIBUSB_DT_BOS_SIZE);
 		return LIBUSB_ERROR_IO;
 	}
 
 	bos_len = libusb_le16_to_cpu(_bos.desc.wTotalLength);
-	usbi_dbg("found BOS descriptor: size %u bytes, %u capabilities",
+	usbi_dbg(ctx, "found BOS descriptor: size %u bytes, %u capabilities",
 		 bos_len, _bos.desc.bNumDeviceCaps);
 	bos_data = calloc(1, bos_len);
 	if (!bos_data)
@@ -875,11 +876,10 @@
 	r = libusb_get_descriptor(dev_handle, LIBUSB_DT_BOS, 0, bos_data, bos_len);
 	if (r >= 0) {
 		if (r != (int)bos_len)
-			usbi_warn(HANDLE_CTX(dev_handle), "short BOS read %d/%u",
-				  r, bos_len);
+			usbi_warn(ctx, "short BOS read %d/%u", r, bos_len);
 		r = parse_bos(HANDLE_CTX(dev_handle), bos, bos_data, r);
 	} else {
-		usbi_err(HANDLE_CTX(dev_handle), "failed to read BOS (%d)", r);
+		usbi_err(ctx, "failed to read BOS (%d)", r);
 	}
 
 	free(bos_data);
diff --git a/libusb/hotplug.c b/libusb/hotplug.c
index 52ce626..4bb2d4e 100644
--- a/libusb/hotplug.c
+++ b/libusb/hotplug.c
@@ -1,7 +1,7 @@
 /* -*- Mode: C; indent-tabs-mode:t ; c-basic-offset:8 -*- */
 /*
  * Hotplug functions for libusb
- * Copyright © 2012-2013 Nathan Hjelm <hjelmn@mac.com>
+ * Copyright © 2012-2021 Nathan Hjelm <hjelmn@mac.com>
  * Copyright © 2012-2013 Peter Stuge <peter@stuge.se>
  *
  * This library is free software; you can redistribute it and/or
@@ -307,7 +307,7 @@
 	/* free any callbacks that have unregistered */
 	for_each_hotplug_cb_safe(ctx, hotplug_cb, next_cb) {
 		if (hotplug_cb->flags & USBI_HOTPLUG_NEEDS_FREE) {
-			usbi_dbg("freeing hotplug cb %p with handle %d",
+			usbi_dbg(ctx, "freeing hotplug cb %p with handle %d",
 				hotplug_cb, hotplug_cb->handle);
 			list_del(&hotplug_cb->list);
 			free(hotplug_cb);
@@ -374,7 +374,7 @@
 
 	usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
 
-	usbi_dbg("new hotplug cb %p with handle %d", hotplug_cb, hotplug_cb->handle);
+	usbi_dbg(ctx, "new hotplug cb %p with handle %d", hotplug_cb, hotplug_cb->handle);
 
 	if ((flags & LIBUSB_HOTPLUG_ENUMERATE) && (events & LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED)) {
 		ssize_t i, len;
@@ -411,7 +411,7 @@
 	if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG))
 		return;
 
-	usbi_dbg("deregister hotplug cb %d", callback_handle);
+	usbi_dbg(ctx, "deregister hotplug cb %d", callback_handle);
 
 	ctx = usbi_get_context(ctx);
 
@@ -449,7 +449,7 @@
 	if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG))
 		return NULL;
 
-	usbi_dbg("get hotplug cb %d user data", callback_handle);
+	usbi_dbg(ctx, "get hotplug cb %d user data", callback_handle);
 
 	ctx = usbi_get_context(ctx);
 
diff --git a/libusb/io.c b/libusb/io.c
index ecd750f..f2743b9 100644
--- a/libusb/io.c
+++ b/libusb/io.c
@@ -1180,12 +1180,12 @@
 #ifdef HAVE_OS_TIMER
 	r = usbi_create_timer(&ctx->timer);
 	if (r == 0) {
-		usbi_dbg("using timer for timeouts");
+		usbi_dbg(ctx, "using timer for timeouts");
 		r = usbi_add_event_source(ctx, USBI_TIMER_OS_HANDLE(&ctx->timer), USBI_TIMER_POLL_EVENTS);
 		if (r < 0)
 			goto err_destroy_timer;
 	} else {
-		usbi_dbg("timer not available for timeouts");
+		usbi_dbg(ctx, "timer not available for timeouts");
 	}
 #endif
 
@@ -1309,7 +1309,6 @@
 	itransfer->priv = ptr;
 	usbi_mutex_init(&itransfer->lock);
 	transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
-	usbi_dbg("transfer %p", transfer);
 	return transfer;
 }
 
@@ -1339,7 +1338,7 @@
 	if (!transfer)
 		return;
 
-	usbi_dbg("transfer %p", transfer);
+	usbi_dbg(TRANSFER_CTX(transfer), "transfer %p", transfer);
 	if (transfer->flags & LIBUSB_TRANSFER_FREE_BUFFER)
 		free(transfer->buffer);
 
@@ -1375,12 +1374,12 @@
 
 		/* act on first transfer that has not already been handled */
 		if (!(itransfer->timeout_flags & (USBI_TRANSFER_TIMEOUT_HANDLED | USBI_TRANSFER_OS_HANDLES_TIMEOUT))) {
-			usbi_dbg("next timeout originally %ums", USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer)->timeout);
+			usbi_dbg(ctx, "next timeout originally %ums", USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer)->timeout);
 			return usbi_arm_timer(&ctx->timer, cur_ts);
 		}
 	}
 
-	usbi_dbg("no timeouts, disarming timer");
+	usbi_dbg(ctx, "no timeouts, disarming timer");
 	return usbi_disarm_timer(&ctx->timer);
 }
 #else
@@ -1437,7 +1436,7 @@
 	if (first && usbi_using_timer(ctx) && TIMESPEC_IS_SET(timeout)) {
 		/* if this transfer has the lowest timeout of all active transfers,
 		 * rearm the timer with this transfer's timeout */
-		usbi_dbg("arm timer for timeout in %ums (first in line)",
+		usbi_dbg(ctx, "arm timer for timeout in %ums (first in line)",
 			USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer)->timeout);
 		r = usbi_arm_timer(&ctx->timer, timeout);
 	}
@@ -1493,7 +1492,7 @@
 	struct libusb_context *ctx = TRANSFER_CTX(transfer);
 	int r;
 
-	usbi_dbg("transfer %p", transfer);
+	usbi_dbg(ctx, "transfer %p", transfer);
 
 	/*
 	 * Important note on locking, this function takes / releases locks
@@ -1581,9 +1580,10 @@
 {
 	struct usbi_transfer *itransfer =
 		LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer);
+	struct libusb_context *ctx = ITRANSFER_CTX(itransfer);
 	int r;
 
-	usbi_dbg("transfer %p", transfer );
+	usbi_dbg(ctx, "transfer %p", transfer );
 	usbi_mutex_lock(&itransfer->lock);
 	if (!(itransfer->state_flags & USBI_TRANSFER_IN_FLIGHT)
 			|| (itransfer->state_flags & USBI_TRANSFER_CANCELLING)) {
@@ -1594,10 +1594,9 @@
 	if (r < 0) {
 		if (r != LIBUSB_ERROR_NOT_FOUND &&
 		    r != LIBUSB_ERROR_NO_DEVICE)
-			usbi_err(TRANSFER_CTX(transfer),
-				"cancel transfer failed error %d", r);
+			usbi_err(ctx, "cancel transfer failed error %d", r);
 		else
-			usbi_dbg("cancel transfer failed error %d", r);
+			usbi_dbg(ctx, "cancel transfer failed error %d", r);
 
 		if (r == LIBUSB_ERROR_NO_DEVICE)
 			itransfer->state_flags |= USBI_TRANSFER_DEVICE_DISAPPEARED;
@@ -1661,12 +1660,13 @@
 	struct libusb_transfer *transfer =
 		USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
 	struct libusb_device_handle *dev_handle = transfer->dev_handle;
+	struct libusb_context *ctx = ITRANSFER_CTX(itransfer);
 	uint8_t flags;
 	int r;
 
 	r = remove_from_flying_list(itransfer);
 	if (r < 0)
-		usbi_err(ITRANSFER_CTX(itransfer), "failed to set timer for next timeout");
+		usbi_err(ctx, "failed to set timer for next timeout");
 
 	usbi_mutex_lock(&itransfer->lock);
 	itransfer->state_flags &= ~USBI_TRANSFER_IN_FLIGHT;
@@ -1678,7 +1678,7 @@
 		if (transfer->type == LIBUSB_TRANSFER_TYPE_CONTROL)
 			rqlen -= LIBUSB_CONTROL_SETUP_SIZE;
 		if (rqlen != itransfer->transferred) {
-			usbi_dbg("interpreting short transfer as error");
+			usbi_dbg(ctx, "interpreting short transfer as error");
 			status = LIBUSB_TRANSFER_ERROR;
 		}
 	}
@@ -1686,7 +1686,7 @@
 	flags = transfer->flags;
 	transfer->status = status;
 	transfer->actual_length = itransfer->transferred;
-	usbi_dbg("transfer %p has callback %p", transfer, transfer->callback);
+	usbi_dbg(ctx, "transfer %p has callback %p", transfer, transfer->callback);
 	if (transfer->callback)
 		transfer->callback(transfer);
 	/* transfer might have been freed by the above call, do not use from
@@ -1714,7 +1714,7 @@
 
 	/* if the URB was cancelled due to timeout, report timeout to the user */
 	if (timed_out) {
-		usbi_dbg("detected timeout cancellation");
+		usbi_dbg(ctx, "detected timeout cancellation");
 		return usbi_handle_transfer_completion(itransfer, LIBUSB_TRANSFER_TIMED_OUT);
 	}
 
@@ -1775,7 +1775,7 @@
 	ru = ctx->device_close;
 	usbi_mutex_unlock(&ctx->event_data_lock);
 	if (ru) {
-		usbi_dbg("someone else is closing a device");
+		usbi_dbg(ctx, "someone else is closing a device");
 		return 1;
 	}
 
@@ -1867,7 +1867,7 @@
 	r = ctx->device_close;
 	usbi_mutex_unlock(&ctx->event_data_lock);
 	if (r) {
-		usbi_dbg("someone else is closing a device");
+		usbi_dbg(ctx, "someone else is closing a device");
 		return 0;
 	}
 
@@ -1896,7 +1896,7 @@
 	r = ctx->device_close;
 	usbi_mutex_unlock(&ctx->event_data_lock);
 	if (r) {
-		usbi_dbg("someone else is closing a device");
+		usbi_dbg(ctx, "someone else is closing a device");
 		return 1;
 	}
 
@@ -1917,7 +1917,7 @@
 {
 	unsigned int event_flags;
 
-	usbi_dbg(" ");
+	usbi_dbg(ctx, " ");
 
 	ctx = usbi_get_context(ctx);
 	usbi_mutex_lock(&ctx->event_data_lock);
@@ -2075,7 +2075,7 @@
 	int hotplug_event = 0;
 	int r = 0;
 
-	usbi_dbg("event triggered");
+	usbi_dbg(ctx, "event triggered");
 
 	list_init(&hotplug_msgs);
 
@@ -2084,26 +2084,26 @@
 
 	/* check if someone modified the event sources */
 	if (ctx->event_flags & USBI_EVENT_EVENT_SOURCES_MODIFIED)
-		usbi_dbg("someone updated the event sources");
+		usbi_dbg(ctx, "someone updated the event sources");
 
 	if (ctx->event_flags & USBI_EVENT_USER_INTERRUPT) {
-		usbi_dbg("someone purposefully interrupted");
+		usbi_dbg(ctx, "someone purposefully interrupted");
 		ctx->event_flags &= ~USBI_EVENT_USER_INTERRUPT;
 	}
 
 	if (ctx->event_flags & USBI_EVENT_HOTPLUG_CB_DEREGISTERED) {
-		usbi_dbg("someone unregistered a hotplug cb");
+		usbi_dbg(ctx, "someone unregistered a hotplug cb");
 		ctx->event_flags &= ~USBI_EVENT_HOTPLUG_CB_DEREGISTERED;
 		hotplug_event = 1;
 	}
 
 	/* check if someone is closing a device */
 	if (ctx->event_flags & USBI_EVENT_DEVICE_CLOSE)
-		usbi_dbg("someone is closing a device");
+		usbi_dbg(ctx, "someone is closing a device");
 
 	/* check for any pending hotplug messages */
 	if (ctx->event_flags & USBI_EVENT_HOTPLUG_MSG_PENDING) {
-		usbi_dbg("hotplug message received");
+		usbi_dbg(ctx, "hotplug message received");
 		ctx->event_flags &= ~USBI_EVENT_HOTPLUG_MSG_PENDING;
 		hotplug_event = 1;
 		assert(!list_empty(&ctx->hotplug_msgs));
@@ -2186,7 +2186,7 @@
 	 * save the additional overhead */
 	usbi_mutex_lock(&ctx->event_data_lock);
 	if (ctx->event_flags & USBI_EVENT_EVENT_SOURCES_MODIFIED) {
-		usbi_dbg("event sources modified, reallocating event data");
+		usbi_dbg(ctx, "event sources modified, reallocating event data");
 
 		/* free anything removed since we last ran */
 		cleanup_removed_event_sources(ctx);
@@ -2333,7 +2333,7 @@
 	if (libusb_try_lock_events(ctx) == 0) {
 		if (completed == NULL || !*completed) {
 			/* we obtained the event lock: do our own event handling */
-			usbi_dbg("doing our own event handling");
+			usbi_dbg(ctx, "doing our own event handling");
 			r = handle_events(ctx, &poll_timeout);
 		}
 		libusb_unlock_events(ctx);
@@ -2351,11 +2351,11 @@
 		/* we hit a race: whoever was event handling earlier finished in the
 		 * time it took us to reach this point. try the cycle again. */
 		libusb_unlock_event_waiters(ctx);
-		usbi_dbg("event handler was active but went away, retrying");
+		usbi_dbg(ctx, "event handler was active but went away, retrying");
 		goto retry;
 	}
 
-	usbi_dbg("another thread is doing event handling");
+	usbi_dbg(ctx, "another thread is doing event handling");
 	r = libusb_wait_for_event(ctx, &poll_timeout);
 
 already_done:
@@ -2550,7 +2550,7 @@
 	usbi_mutex_lock(&ctx->flying_transfers_lock);
 	if (list_empty(&ctx->flying_transfers)) {
 		usbi_mutex_unlock(&ctx->flying_transfers_lock);
-		usbi_dbg("no URBs, no timeout!");
+		usbi_dbg(ctx, "no URBs, no timeout!");
 		return 0;
 	}
 
@@ -2569,19 +2569,19 @@
 	usbi_mutex_unlock(&ctx->flying_transfers_lock);
 
 	if (!TIMESPEC_IS_SET(&next_timeout)) {
-		usbi_dbg("no URB with timeout or all handled by OS; no timeout!");
+		usbi_dbg(ctx, "no URB with timeout or all handled by OS; no timeout!");
 		return 0;
 	}
 
 	usbi_get_monotonic_time(&systime);
 
 	if (!TIMESPEC_CMP(&systime, &next_timeout, <)) {
-		usbi_dbg("first timeout already expired");
+		usbi_dbg(ctx, "first timeout already expired");
 		timerclear(tv);
 	} else {
 		TIMESPEC_SUB(&next_timeout, &systime, &next_timeout);
 		TIMESPEC_TO_TIMEVAL(tv, &next_timeout);
-		usbi_dbg("next timeout in %ld.%06lds", (long)tv->tv_sec, (long)tv->tv_usec);
+		usbi_dbg(ctx, "next timeout in %ld.%06lds", (long)tv->tv_sec, (long)tv->tv_usec);
 	}
 
 	return 1;
@@ -2652,7 +2652,7 @@
 	if (!ievent_source)
 		return LIBUSB_ERROR_NO_MEM;
 
-	usbi_dbg("add " USBI_OS_HANDLE_FORMAT_STRING " events %d", os_handle, poll_events);
+	usbi_dbg(ctx, "add " USBI_OS_HANDLE_FORMAT_STRING " events %d", os_handle, poll_events);
 	ievent_source->data.os_handle = os_handle;
 	ievent_source->data.poll_events = poll_events;
 	usbi_mutex_lock(&ctx->event_data_lock);
@@ -2674,7 +2674,7 @@
 	struct usbi_event_source *ievent_source;
 	int found = 0;
 
-	usbi_dbg("remove " USBI_OS_HANDLE_FORMAT_STRING, os_handle);
+	usbi_dbg(ctx, "remove " USBI_OS_HANDLE_FORMAT_STRING, os_handle);
 	usbi_mutex_lock(&ctx->event_data_lock);
 	for_each_event_source(ctx, ievent_source) {
 		if (ievent_source->data.os_handle == os_handle) {
@@ -2684,7 +2684,7 @@
 	}
 
 	if (!found) {
-		usbi_dbg("couldn't find " USBI_OS_HANDLE_FORMAT_STRING " to remove", os_handle);
+		usbi_dbg(ctx, "couldn't find " USBI_OS_HANDLE_FORMAT_STRING " to remove", os_handle);
 		usbi_mutex_unlock(&ctx->event_data_lock);
 		return;
 	}
@@ -2783,7 +2783,7 @@
 	struct usbi_transfer *cur;
 	struct usbi_transfer *to_cancel;
 
-	usbi_dbg("device %d.%d",
+	usbi_dbg(ctx, "device %d.%d",
 		dev_handle->dev->bus_number, dev_handle->dev->device_address);
 
 	/* terminate all pending transfers with the LIBUSB_TRANSFER_NO_DEVICE
@@ -2818,7 +2818,7 @@
 		if (!to_cancel)
 			break;
 
-		usbi_dbg("cancelling transfer %p from disconnect",
+		usbi_dbg(ctx, "cancelling transfer %p from disconnect",
 			 USBI_TRANSFER_TO_LIBUSB_TRANSFER(to_cancel));
 
 		usbi_mutex_lock(&to_cancel->lock);
diff --git a/libusb/libusbi.h b/libusb/libusbi.h
index 31d4917..158a9af 100644
--- a/libusb/libusbi.h
+++ b/libusb/libusbi.h
@@ -317,14 +317,14 @@
 #define usbi_err(ctx, ...)	_usbi_log(ctx, LIBUSB_LOG_LEVEL_ERROR, __VA_ARGS__)
 #define usbi_warn(ctx, ...)	_usbi_log(ctx, LIBUSB_LOG_LEVEL_WARNING, __VA_ARGS__)
 #define usbi_info(ctx, ...)	_usbi_log(ctx, LIBUSB_LOG_LEVEL_INFO, __VA_ARGS__)
-#define usbi_dbg(...)		_usbi_log(NULL, LIBUSB_LOG_LEVEL_DEBUG, __VA_ARGS__)
+#define usbi_dbg(ctx ,...)      	_usbi_log(ctx, LIBUSB_LOG_LEVEL_DEBUG, __VA_ARGS__)
 
 #else /* ENABLE_LOGGING */
 
 #define usbi_err(ctx, ...)	UNUSED(ctx)
 #define usbi_warn(ctx, ...)	UNUSED(ctx)
 #define usbi_info(ctx, ...)	UNUSED(ctx)
-#define usbi_dbg(...)		do {} while (0)
+#define usbi_dbg(ctx, ...)	do {} while (0)
 
 #endif /* ENABLE_LOGGING */
 
diff --git a/libusb/os/darwin_usb.c b/libusb/os/darwin_usb.c
index d0180e4..afa13c2 100644
--- a/libusb/os/darwin_usb.c
+++ b/libusb/os/darwin_usb.c
@@ -89,7 +89,7 @@
 static enum libusb_error process_new_device (struct libusb_context *ctx, struct darwin_cached_device *cached_device,
                                              UInt64 old_session_id);
 
-static enum libusb_error darwin_get_cached_device(io_service_t service, struct darwin_cached_device **cached_out,
+static enum libusb_error darwin_get_cached_device(struct libusb_context *ctx, io_service_t service, struct darwin_cached_device **cached_out,
                                                   UInt64 *old_session_id);
 
 #if defined(ENABLE_LOGGING)
@@ -189,7 +189,9 @@
 
   uint8_t i, iface;
 
-  usbi_dbg ("converting ep address 0x%02x to pipeRef and interface", ep);
+  struct libusb_context *ctx = HANDLE_CTX(dev_handle);
+
+  usbi_dbg (ctx, "converting ep address 0x%02x to pipeRef and interface", ep);
 
   for (iface = 0 ; iface < USB_MAXINTERFACES ; iface++) {
     cInterface = &priv->interfaces[iface];
@@ -205,7 +207,7 @@
           if (interface_out)
             *interface_out = cInterface;
 
-          usbi_dbg ("pipe %d on interface %d matches", *pipep, iface);
+          usbi_dbg (ctx, "pipe %d on interface %d matches", *pipep, iface);
           return LIBUSB_SUCCESS;
         }
       }
@@ -287,7 +289,7 @@
   return success;
 }
 
-static usb_device_t **darwin_device_from_service (io_service_t service)
+static usb_device_t **darwin_device_from_service (struct libusb_context *ctx, io_service_t service)
 {
   io_cf_plugin_ref_t *plugInInterface = NULL;
   usb_device_t **device;
@@ -306,14 +308,14 @@
       break;
     }
 
-    usbi_dbg ("set up plugin for service retry: %s", darwin_error_str (kresult));
+    usbi_dbg (ctx, "set up plugin for service retry: %s", darwin_error_str (kresult));
 
     /* sleep for a little while before trying again */
     nanosleep(&(struct timespec){.tv_sec = 0, .tv_nsec = 1000}, NULL);
   }
 
   if (kIOReturnSuccess != kresult || !plugInInterface) {
-    usbi_dbg ("could not set up plugin for service: %s", darwin_error_str (kresult));
+    usbi_dbg (ctx, "could not set up plugin for service: %s", darwin_error_str (kresult));
     return NULL;
   }
 
@@ -336,7 +338,7 @@
   usbi_mutex_lock(&active_contexts_lock);
 
   while ((service = IOIteratorNext(add_devices))) {
-    ret = darwin_get_cached_device (service, &cached_device, &old_session_id);
+    ret = darwin_get_cached_device (NULL, service, &cached_device, &old_session_id);
     if (ret < 0 || !cached_device->can_enumerate) {
       continue;
     }
@@ -347,7 +349,7 @@
     }
 
     if (cached_device->in_reenumerate) {
-      usbi_dbg ("cached device in reset state. reset complete...");
+      usbi_dbg (NULL, "cached device in reset state. reset complete...");
       cached_device->in_reenumerate = false;
     }
 
@@ -387,7 +389,7 @@
         if (old_device->in_reenumerate) {
           /* device is re-enumerating. do not dereference the device at this time. libusb_reset_device()
            * will deref if needed. */
-          usbi_dbg ("detected device detached due to re-enumeration. sessionID: 0x%" PRIx64 ", locationID: 0x%" PRIx64,
+          usbi_dbg (NULL, "detected device detached due to re-enumeration. sessionID: 0x%" PRIx64 ", locationID: 0x%" PRIx64,
                     session, locationID);
 
           /* the device object is no longer usable so go ahead and release it */
@@ -411,7 +413,7 @@
     }
 
     for_each_context(ctx) {
-      usbi_dbg ("notifying context %p of device disconnect", ctx);
+      usbi_dbg (ctx, "notifying context %p of device disconnect", ctx);
 
       dev = usbi_get_device_by_session_id(ctx, (unsigned long) session);
       if (dev) {
@@ -481,7 +483,7 @@
   io_iterator_t          libusb_rem_device_iterator;
   io_iterator_t          libusb_add_device_iterator;
 
-  usbi_dbg ("creating hotplug event source");
+  usbi_dbg (ctx, "creating hotplug event source");
 
   runloop = CFRunLoopGetCurrent ();
   CFRetain (runloop);
@@ -528,7 +530,7 @@
   darwin_clear_iterator (libusb_rem_device_iterator);
   darwin_clear_iterator (libusb_add_device_iterator);
 
-  usbi_dbg ("darwin event thread ready to receive events");
+  usbi_dbg (ctx, "darwin event thread ready to receive events");
 
   /* signal the main thread that the hotplug runloop has been created. */
   pthread_mutex_lock (&libusb_darwin_at_mutex);
@@ -540,7 +542,7 @@
   /* run the runloop */
   CFRunLoopRun();
 
-  usbi_dbg ("darwin event thread exiting");
+  usbi_dbg (ctx, "darwin event thread exiting");
 
   /* signal the main thread that the hotplug runloop has finished. */
   pthread_mutex_lock (&libusb_darwin_at_mutex);
@@ -743,7 +745,7 @@
      not usable anyway */
   if (0x05ac == libusb_le16_to_cpu (dev->dev_descriptor.idVendor) &&
       0x8005 == libusb_le16_to_cpu (dev->dev_descriptor.idProduct)) {
-    usbi_dbg ("ignoring configuration on root hub simulation");
+    usbi_dbg (ctx, "ignoring configuration on root hub simulation");
     dev->active_config = 0;
     return LIBUSB_SUCCESS;
   }
@@ -786,7 +788,7 @@
     /* not configured */
     dev->active_config = 0;
 
-  usbi_dbg ("active config: %u, first config: %u", dev->active_config, dev->first_config);
+  usbi_dbg (ctx, "active config: %u, first config: %u", dev->active_config, dev->first_config);
 
   return LIBUSB_SUCCESS;
 }
@@ -811,7 +813,7 @@
   return (*device)->DeviceRequestTO (device, &req);
 }
 
-static enum libusb_error darwin_cache_device_descriptor (struct darwin_cached_device *dev) {
+static enum libusb_error darwin_cache_device_descriptor (struct libusb_context *ctx, struct darwin_cached_device *dev) {
   usb_device_t **device = dev->device;
   int retries = 1;
   long delay = 30000; // microseconds
@@ -849,7 +851,7 @@
                                     0 == dev->dev_descriptor.bcdUSB)) {
       /* work around for incorrectly configured devices */
       if (try_reconfigure && is_open) {
-        usbi_dbg("descriptor appears to be invalid. resetting configuration before trying again...");
+        usbi_dbg(ctx, "descriptor appears to be invalid. resetting configuration before trying again...");
 
         /* set the first configuration */
         (*device)->SetConfiguration(device, 1);
@@ -880,7 +882,7 @@
         if (kIOReturnSuccess != ret2) {
           /* prevent log spew from poorly behaving devices.  this indicates the
              os actually had trouble communicating with the device */
-          usbi_dbg("could not retrieve device descriptor. failed to unsuspend: %s",darwin_error_str(ret2));
+          usbi_dbg(ctx, "could not retrieve device descriptor. failed to unsuspend: %s",darwin_error_str(ret2));
         } else
           unsuspended = 1;
 
@@ -889,7 +891,7 @@
     }
 
     if (kIOReturnSuccess != ret) {
-      usbi_dbg("kernel responded with code: 0x%08x. sleeping for %ld ms before trying again", ret, delay/1000);
+      usbi_dbg(ctx, "kernel responded with code: 0x%08x. sleeping for %ld ms before trying again", ret, delay/1000);
       /* sleep for a little while before trying again */
       nanosleep(&(struct timespec){delay / 1000000, (delay * 1000) % 1000000000}, NULL);
     }
@@ -905,10 +907,10 @@
   if (ret != kIOReturnSuccess) {
     /* a debug message was already printed out for this error */
     if (LIBUSB_CLASS_HUB == bDeviceClass)
-      usbi_dbg ("could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
+      usbi_dbg (ctx, "could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
                 idVendor, idProduct, darwin_error_str (ret), ret);
     else
-      usbi_warn (NULL, "could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
+      usbi_warn (ctx, "could not retrieve device descriptor %.4x:%.4x: %s (%x). skipping device",
                  idVendor, idProduct, darwin_error_str (ret), ret);
     return darwin_to_libusb (ret);
   }
@@ -921,20 +923,20 @@
     return LIBUSB_ERROR_NO_DEVICE;
   }
 
-  usbi_dbg ("cached device descriptor:");
-  usbi_dbg ("  bDescriptorType:    0x%02x", dev->dev_descriptor.bDescriptorType);
-  usbi_dbg ("  bcdUSB:             0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdUSB));
-  usbi_dbg ("  bDeviceClass:       0x%02x", dev->dev_descriptor.bDeviceClass);
-  usbi_dbg ("  bDeviceSubClass:    0x%02x", dev->dev_descriptor.bDeviceSubClass);
-  usbi_dbg ("  bDeviceProtocol:    0x%02x", dev->dev_descriptor.bDeviceProtocol);
-  usbi_dbg ("  bMaxPacketSize0:    0x%02x", dev->dev_descriptor.bMaxPacketSize0);
-  usbi_dbg ("  idVendor:           0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.idVendor));
-  usbi_dbg ("  idProduct:          0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
-  usbi_dbg ("  bcdDevice:          0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdDevice));
-  usbi_dbg ("  iManufacturer:      0x%02x", dev->dev_descriptor.iManufacturer);
-  usbi_dbg ("  iProduct:           0x%02x", dev->dev_descriptor.iProduct);
-  usbi_dbg ("  iSerialNumber:      0x%02x", dev->dev_descriptor.iSerialNumber);
-  usbi_dbg ("  bNumConfigurations: 0x%02x", dev->dev_descriptor.bNumConfigurations);
+  usbi_dbg (ctx, "cached device descriptor:");
+  usbi_dbg (ctx, "  bDescriptorType:    0x%02x", dev->dev_descriptor.bDescriptorType);
+  usbi_dbg (ctx, "  bcdUSB:             0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdUSB));
+  usbi_dbg (ctx, "  bDeviceClass:       0x%02x", dev->dev_descriptor.bDeviceClass);
+  usbi_dbg (ctx, "  bDeviceSubClass:    0x%02x", dev->dev_descriptor.bDeviceSubClass);
+  usbi_dbg (ctx, "  bDeviceProtocol:    0x%02x", dev->dev_descriptor.bDeviceProtocol);
+  usbi_dbg (ctx, "  bMaxPacketSize0:    0x%02x", dev->dev_descriptor.bMaxPacketSize0);
+  usbi_dbg (ctx, "  idVendor:           0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.idVendor));
+  usbi_dbg (ctx, "  idProduct:          0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.idProduct));
+  usbi_dbg (ctx, "  bcdDevice:          0x%04x", libusb_le16_to_cpu (dev->dev_descriptor.bcdDevice));
+  usbi_dbg (ctx, "  iManufacturer:      0x%02x", dev->dev_descriptor.iManufacturer);
+  usbi_dbg (ctx, "  iProduct:           0x%02x", dev->dev_descriptor.iProduct);
+  usbi_dbg (ctx, "  iSerialNumber:      0x%02x", dev->dev_descriptor.iSerialNumber);
+  usbi_dbg (ctx, "  bNumConfigurations: 0x%02x", dev->dev_descriptor.bNumConfigurations);
 
   dev->can_enumerate = 1;
 
@@ -978,7 +980,7 @@
   return false;
 }
 
-static enum libusb_error darwin_get_cached_device(io_service_t service, struct darwin_cached_device **cached_out,
+static enum libusb_error darwin_get_cached_device(struct libusb_context *ctx, io_service_t service, struct darwin_cached_device **cached_out,
                                                   UInt64 *old_session_id) {
   struct darwin_cached_device *new_device;
   UInt64 sessionID = 0, parent_sessionID = 0;
@@ -995,28 +997,28 @@
   (void) get_ioregistry_value_number (service, CFSTR("sessionID"), kCFNumberSInt64Type, &sessionID);
   (void) get_ioregistry_value_number (service, CFSTR("locationID"), kCFNumberSInt32Type, &locationID);
   if (!get_device_port (service, &port)) {
-    usbi_dbg("could not get connected port number");
+    usbi_dbg(ctx, "could not get connected port number");
   }
 
-  usbi_dbg("finding cached device for sessionID 0x%" PRIx64, sessionID);
+  usbi_dbg(ctx, "finding cached device for sessionID 0x%" PRIx64, sessionID);
 
   if (get_device_parent_sessionID(service, &parent_sessionID)) {
-    usbi_dbg("parent sessionID: 0x%" PRIx64, parent_sessionID);
+    usbi_dbg(ctx, "parent sessionID: 0x%" PRIx64, parent_sessionID);
   }
 
   usbi_mutex_lock(&darwin_cached_devices_lock);
   do {
     list_for_each_entry(new_device, &darwin_cached_devices, list, struct darwin_cached_device) {
-      usbi_dbg("matching sessionID/locationID 0x%" PRIx64 "/0x%x against cached device with sessionID/locationID 0x%" PRIx64 "/0x%x",
+      usbi_dbg(ctx, "matching sessionID/locationID 0x%" PRIx64 "/0x%x against cached device with sessionID/locationID 0x%" PRIx64 "/0x%x",
                sessionID, locationID, new_device->session, new_device->location);
       if (new_device->location == locationID && new_device->in_reenumerate) {
-        usbi_dbg ("found cached device with matching location that is being re-enumerated");
+        usbi_dbg (ctx, "found cached device with matching location that is being re-enumerated");
         *old_session_id = new_device->session;
         break;
       }
 
       if (new_device->session == sessionID) {
-        usbi_dbg("using cached device for device");
+        usbi_dbg(ctx, "using cached device for device");
         *cached_out = new_device;
         break;
       }
@@ -1025,9 +1027,9 @@
     if (*cached_out)
       break;
 
-    usbi_dbg("caching new device with sessionID 0x%" PRIx64, sessionID);
+    usbi_dbg(ctx, "caching new device with sessionID 0x%" PRIx64, sessionID);
 
-    device = darwin_device_from_service (service);
+    device = darwin_device_from_service (ctx, service);
     if (!device) {
       ret = LIBUSB_ERROR_NO_DEVICE;
       break;
@@ -1068,7 +1070,7 @@
     IOObjectRetain (service);
 
     /* cache the device descriptor */
-    ret = darwin_cache_device_descriptor(new_device);
+    ret = darwin_cache_device_descriptor(ctx, new_device);
     if (ret)
       break;
 
@@ -1100,14 +1102,14 @@
       break;
 
     if (0 != old_session_id) {
-      usbi_dbg ("re-using existing device from context %p for with session 0x%" PRIx64 " new session 0x%" PRIx64,
+      usbi_dbg (ctx, "re-using existing device from context %p for with session 0x%" PRIx64 " new session 0x%" PRIx64,
                 ctx, old_session_id, cached_device->session);
       /* save the libusb device before the session id is updated */
       dev = usbi_get_device_by_session_id (ctx, (unsigned long) old_session_id);
     }
 
     if (!dev) {
-      usbi_dbg ("allocating new device in context %p for with session 0x%" PRIx64,
+      usbi_dbg (ctx, "allocating new device in context %p for with session 0x%" PRIx64,
                 ctx, cached_device->session);
 
       dev = usbi_alloc_device(ctx, (unsigned long) cached_device->session);
@@ -1164,7 +1166,7 @@
     if (ret < 0)
       break;
 
-    usbi_dbg ("found device with address %d port = %d parent = %p at %p", dev->device_address,
+    usbi_dbg (ctx, "found device with address %d port = %d parent = %p at %p", dev->device_address,
               dev->port_number, (void *) dev->parent_dev, priv->dev->sys_path);
 
   } while (0);
@@ -1191,7 +1193,7 @@
     return darwin_to_libusb (kresult);
 
   while ((service = IOIteratorNext (deviceIterator))) {
-    ret = darwin_get_cached_device (service, &cached_device, &old_session_id);
+    ret = darwin_get_cached_device (ctx, service, &cached_device, &old_session_id);
     if (ret < 0 || !cached_device->can_enumerate) {
       continue;
     }
@@ -1250,7 +1252,7 @@
   /* device opened successfully */
   dpriv->open_count++;
 
-  usbi_dbg ("device open for access");
+  usbi_dbg (HANDLE_CTX(dev_handle), "device open for access");
 
   return 0;
 }
@@ -1384,13 +1386,15 @@
   UInt8 dont_care1, dont_care3;
   UInt16 dont_care2;
   int rc;
+  struct libusb_context *ctx = HANDLE_CTX (dev_handle);
 
-  usbi_dbg ("building table of endpoints.");
+
+  usbi_dbg (ctx, "building table of endpoints.");
 
   /* retrieve the total number of endpoints on this interface */
   kresult = (*(cInterface->interface))->GetNumEndpoints(cInterface->interface, &numep);
   if (kresult != kIOReturnSuccess) {
-    usbi_err (HANDLE_CTX (dev_handle), "can't get number of endpoints for interface: %s", darwin_error_str(kresult));
+    usbi_err (ctx, "can't get number of endpoints for interface: %s", darwin_error_str(kresult));
     return darwin_to_libusb (kresult);
   }
 
@@ -1423,7 +1427,7 @@
       cInterface->endpoint_addrs[i - 1] = (UInt8)(((kUSBIn == direction) << kUSBRqDirnShift) | (number & LIBUSB_ENDPOINT_ADDRESS_MASK));
     }
 
-    usbi_dbg ("interface: %i pipe %i: dir: %i number: %i", iface, i, cInterface->endpoint_addrs[i - 1] >> kUSBRqDirnShift,
+    usbi_dbg (ctx, "interface: %i pipe %i: dir: %i number: %i", iface, i, cInterface->endpoint_addrs[i - 1] >> kUSBRqDirnShift,
               cInterface->endpoint_addrs[i - 1] & LIBUSB_ENDPOINT_ADDRESS_MASK);
   }
 
@@ -1444,30 +1448,32 @@
   /* current interface */
   struct darwin_interface *cInterface = &priv->interfaces[iface];
 
+  struct libusb_context *ctx = HANDLE_CTX (dev_handle);
+
   kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
   if (kresult != kIOReturnSuccess)
     return darwin_to_libusb (kresult);
 
   /* make sure we have an interface */
   if (!usbInterface && dpriv->first_config != 0) {
-    usbi_info (HANDLE_CTX (dev_handle), "no interface found; setting configuration: %d", dpriv->first_config);
+    usbi_info (ctx, "no interface found; setting configuration: %d", dpriv->first_config);
 
     /* set the configuration */
     ret = darwin_set_configuration (dev_handle, (int) dpriv->first_config);
     if (ret != LIBUSB_SUCCESS) {
-      usbi_err (HANDLE_CTX (dev_handle), "could not set configuration");
+      usbi_err (ctx, "could not set configuration");
       return ret;
     }
 
     kresult = darwin_get_interface (dpriv->device, iface, &usbInterface);
     if (kresult != kIOReturnSuccess) {
-      usbi_err (HANDLE_CTX (dev_handle), "darwin_get_interface: %s", darwin_error_str(kresult));
+      usbi_err (ctx, "darwin_get_interface: %s", darwin_error_str(kresult));
       return darwin_to_libusb (kresult);
     }
   }
 
   if (!usbInterface) {
-    usbi_info (HANDLE_CTX (dev_handle), "interface not found");
+    usbi_info (ctx, "interface not found");
     return LIBUSB_ERROR_NOT_FOUND;
   }
 
@@ -1479,12 +1485,12 @@
   (void)IOObjectRelease (usbInterface);
 
   if (kresult != kIOReturnSuccess) {
-    usbi_err (HANDLE_CTX (dev_handle), "IOCreatePlugInInterfaceForService: %s", darwin_error_str(kresult));
+    usbi_err (ctx, "IOCreatePlugInInterfaceForService: %s", darwin_error_str(kresult));
     return darwin_to_libusb (kresult);
   }
 
   if (!plugInInterface) {
-    usbi_err (HANDLE_CTX (dev_handle), "plugin interface not found");
+    usbi_err (ctx, "plugin interface not found");
     return LIBUSB_ERROR_NOT_FOUND;
   }
 
@@ -1496,14 +1502,14 @@
   /* Use release instead of IODestroyPlugInInterface to avoid stopping IOServices associated with this device */
   (*plugInInterface)->Release (plugInInterface);
   if (kresult != kIOReturnSuccess || !cInterface->interface) {
-    usbi_err (HANDLE_CTX (dev_handle), "QueryInterface: %s", darwin_error_str(kresult));
+    usbi_err (ctx, "QueryInterface: %s", darwin_error_str(kresult));
     return darwin_to_libusb (kresult);
   }
 
   /* claim the interface */
   kresult = (*(cInterface->interface))->USBInterfaceOpen(cInterface->interface);
   if (kresult != kIOReturnSuccess) {
-    usbi_info (HANDLE_CTX (dev_handle), "USBInterfaceOpen: %s", darwin_error_str(kresult));
+    usbi_info (ctx, "USBInterfaceOpen: %s", darwin_error_str(kresult));
     return darwin_to_libusb (kresult);
   }
 
@@ -1512,7 +1518,7 @@
   if (ret) {
     /* this should not happen */
     darwin_release_interface (dev_handle, iface);
-    usbi_err (HANDLE_CTX (dev_handle), "could not build endpoint table");
+    usbi_err (ctx, "could not build endpoint table");
     return ret;
   }
 
@@ -1521,7 +1527,7 @@
   /* create async event source */
   kresult = (*(cInterface->interface))->CreateInterfaceAsyncEventSource (cInterface->interface, &cInterface->cfSource);
   if (kresult != kIOReturnSuccess) {
-    usbi_err (HANDLE_CTX (dev_handle), "could not create async event source");
+    usbi_err (ctx, "could not create async event source");
 
     /* can't continue without an async event source */
     (void)darwin_release_interface (dev_handle, iface);
@@ -1532,7 +1538,7 @@
   /* add the cfSource to the async thread's run loop */
   CFRunLoopAddSource(libusb_darwin_acfl, cInterface->cfSource, kCFRunLoopDefaultMode);
 
-  usbi_dbg ("interface opened");
+  usbi_dbg (ctx, "interface opened");
 
   return LIBUSB_SUCCESS;
 }
@@ -1652,6 +1658,8 @@
   int open_count = dpriv->open_count;
   int ret;
 
+  struct libusb_context *ctx = HANDLE_CTX (dev_handle);
+
   /* clear claimed interfaces temporarily */
   dev_handle->claimed_interfaces = 0;
 
@@ -1671,16 +1679,16 @@
   }
 
   if (dpriv->active_config != active_config) {
-    usbi_dbg ("darwin/restore_state: restoring configuration %d...", active_config);
+    usbi_dbg (ctx, "darwin/restore_state: restoring configuration %d...", active_config);
 
     ret = darwin_set_configuration (dev_handle, active_config);
     if (LIBUSB_SUCCESS != ret) {
-      usbi_dbg ("darwin/restore_state: could not restore configuration");
+      usbi_dbg (ctx, "darwin/restore_state: could not restore configuration");
       return LIBUSB_ERROR_NOT_FOUND;
     }
   }
 
-  usbi_dbg ("darwin/restore_state: reclaiming interfaces");
+  usbi_dbg (ctx, "darwin/restore_state: reclaiming interfaces");
 
   if (claimed_interfaces) {
     for (uint8_t iface = 0 ; iface < USB_MAXINTERFACES ; ++iface) {
@@ -1688,11 +1696,11 @@
         continue;
       }
 
-      usbi_dbg ("darwin/restore_state: re-claiming interface %u", iface);
+      usbi_dbg (ctx, "darwin/restore_state: re-claiming interface %u", iface);
 
       ret = darwin_claim_interface (dev_handle, iface);
       if (LIBUSB_SUCCESS != ret) {
-        usbi_dbg ("darwin/restore_state: could not claim interface %u", iface);
+        usbi_dbg (ctx, "darwin/restore_state: could not claim interface %u", iface);
         return LIBUSB_ERROR_NOT_FOUND;
       }
 
@@ -1700,7 +1708,7 @@
     }
   }
 
-  usbi_dbg ("darwin/restore_state: device state restored");
+  usbi_dbg (ctx, "darwin/restore_state: device state restored");
 
   return LIBUSB_SUCCESS;
 }
@@ -1717,6 +1725,8 @@
   UInt8 i;
   UInt32 time;
 
+  struct libusb_context *ctx = HANDLE_CTX (dev_handle);
+
   if (dpriv->in_reenumerate) {
     /* ack, two (or more) threads are trying to reset the device! abort! */
     return LIBUSB_ERROR_NOT_FOUND;
@@ -1745,49 +1755,49 @@
   /* from macOS 10.11 ResetDevice no longer does anything so just use USBDeviceReEnumerate */
   kresult = (*(dpriv->device))->USBDeviceReEnumerate (dpriv->device, options);
   if (kresult != kIOReturnSuccess) {
-    usbi_err (HANDLE_CTX (dev_handle), "USBDeviceReEnumerate: %s", darwin_error_str (kresult));
+    usbi_err (ctx, "USBDeviceReEnumerate: %s", darwin_error_str (kresult));
     dpriv->in_reenumerate = false;
     return darwin_to_libusb (kresult);
   }
 
   /* capture mode does not re-enumerate but it does require re-open */
   if (capture) {
-    usbi_dbg ("darwin/reenumerate_device: restoring state...");
+    usbi_dbg (ctx, "darwin/reenumerate_device: restoring state...");
     dpriv->in_reenumerate = false;
     return darwin_restore_state (dev_handle, active_config, claimed_interfaces);
   }
 
-  usbi_dbg ("darwin/reenumerate_device: waiting for re-enumeration to complete...");
+  usbi_dbg (ctx, "darwin/reenumerate_device: waiting for re-enumeration to complete...");
 
   time = 0;
   while (dpriv->in_reenumerate) {
     struct timespec delay = {.tv_sec = 0, .tv_nsec = 1000};
     nanosleep (&delay, NULL);
     if (time++ >= DARWIN_REENUMERATE_TIMEOUT_US) {
-      usbi_err (HANDLE_CTX (dev_handle), "darwin/reenumerate_device: timeout waiting for reenumerate");
+      usbi_err (ctx, "darwin/reenumerate_device: timeout waiting for reenumerate");
       dpriv->in_reenumerate = false;
       return LIBUSB_ERROR_TIMEOUT;
     }
   }
 
   /* compare descriptors */
-  usbi_dbg ("darwin/reenumerate_device: checking whether descriptors changed");
+  usbi_dbg (ctx, "darwin/reenumerate_device: checking whether descriptors changed");
 
   if (memcmp (&descriptor, &dpriv->dev_descriptor, sizeof (descriptor))) {
     /* device descriptor changed. need to return not found. */
-    usbi_dbg ("darwin/reenumerate_device: device descriptor changed");
+    usbi_dbg (ctx, "darwin/reenumerate_device: device descriptor changed");
     return LIBUSB_ERROR_NOT_FOUND;
   }
 
   for (i = 0 ; i < descriptor.bNumConfigurations ; ++i) {
     (void) (*(dpriv->device))->GetConfigurationDescriptorPtr (dpriv->device, i, &cached_configuration);
     if (memcmp (cached_configuration, cached_configurations + i, sizeof (cached_configurations[i]))) {
-      usbi_dbg ("darwin/reenumerate_device: configuration descriptor %d changed", i);
+      usbi_dbg (ctx, "darwin/reenumerate_device: configuration descriptor %d changed", i);
       return LIBUSB_ERROR_NOT_FOUND;
     }
   }
 
-  usbi_dbg ("darwin/reenumerate_device: device reset complete. restoring state...");
+  usbi_dbg (ctx, "darwin/reenumerate_device: device reset complete. restoring state...");
 
   return darwin_restore_state (dev_handle, active_config, claimed_interfaces);
 }
@@ -2112,8 +2122,10 @@
   uint8_t pipeRef, iface;
   IOReturn kresult;
 
+  struct libusb_context *ctx = ITRANSFER_CTX (itransfer);
+
   if (ep_to_pipeRef (transfer->dev_handle, transfer->endpoint, &pipeRef, &iface, &cInterface) != 0) {
-    usbi_err (TRANSFER_CTX (transfer), "endpoint not found on any open interface");
+    usbi_err (ctx, "endpoint not found on any open interface");
 
     return LIBUSB_ERROR_NOT_FOUND;
   }
@@ -2121,7 +2133,7 @@
   if (!dpriv->device)
     return LIBUSB_ERROR_NO_DEVICE;
 
-  usbi_warn (ITRANSFER_CTX (itransfer), "aborting all transactions on interface %d pipe %d", iface, pipeRef);
+  usbi_warn (ctx, "aborting all transactions on interface %d pipe %d", iface, pipeRef);
 
   /* abort transactions */
 #if InterfaceVersion >= 550
@@ -2131,7 +2143,7 @@
 #endif
     (*(cInterface->interface))->AbortPipe (cInterface->interface, pipeRef);
 
-  usbi_dbg ("calling clear pipe stall to clear the data toggle bit");
+  usbi_dbg (ctx, "calling clear pipe stall to clear the data toggle bit");
 
   /* newer versions of darwin support clearing additional bits on the device's endpoint */
   kresult = (*(cInterface->interface))->ClearPipeStallBothEnds(cInterface->interface, pipeRef);
@@ -2160,7 +2172,7 @@
   struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
   struct darwin_transfer_priv *tpriv = usbi_get_transfer_priv(itransfer);
 
-  usbi_dbg ("an async io operation has completed");
+  usbi_dbg (TRANSFER_CTX(transfer), "an async io operation has completed");
 
   /* if requested write a zero packet */
   if (kIOReturnSuccess == result && IS_XFEROUT(transfer) && transfer->flags & LIBUSB_TRANSFER_ADD_ZERO_PACKET) {
@@ -2183,6 +2195,8 @@
   if (itransfer->timeout_flags & USBI_TRANSFER_TIMED_OUT)
     result = kIOUSBTransactionTimeout;
 
+  struct libusb_context *ctx = ITRANSFER_CTX (itransfer);
+
   switch (result) {
   case kIOReturnUnderrun:
   case kIOReturnSuccess:
@@ -2190,17 +2204,17 @@
   case kIOReturnAborted:
     return LIBUSB_TRANSFER_CANCELLED;
   case kIOUSBPipeStalled:
-    usbi_dbg ("transfer error: pipe is stalled");
+    usbi_dbg (ctx, "transfer error: pipe is stalled");
     return LIBUSB_TRANSFER_STALL;
   case kIOReturnOverrun:
-    usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: data overrun");
+    usbi_warn (ctx, "transfer error: data overrun");
     return LIBUSB_TRANSFER_OVERFLOW;
   case kIOUSBTransactionTimeout:
-    usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: timed out");
+    usbi_warn (ctx, "transfer error: timed out");
     itransfer->timeout_flags |= USBI_TRANSFER_TIMED_OUT;
     return LIBUSB_TRANSFER_TIMED_OUT;
   default:
-    usbi_warn (ITRANSFER_CTX (itransfer), "transfer error: %s (value = 0x%08x)", darwin_error_str (result), result);
+    usbi_warn (ctx, "transfer error: %s (value = 0x%08x)", darwin_error_str (result), result);
     return LIBUSB_TRANSFER_ERROR;
   }
 }
@@ -2211,18 +2225,19 @@
   const unsigned char max_transfer_type = LIBUSB_TRANSFER_TYPE_BULK_STREAM;
   const char *transfer_types[] = {"control", "isoc", "bulk", "interrupt", "bulk-stream", NULL};
   bool is_isoc = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS == transfer->type;
+  struct libusb_context *ctx = ITRANSFER_CTX (itransfer);
 
   if (transfer->type > max_transfer_type) {
-    usbi_err (TRANSFER_CTX(transfer), "unknown endpoint type %d", transfer->type);
+    usbi_err (ctx, "unknown endpoint type %d", transfer->type);
     return LIBUSB_ERROR_INVALID_PARAM;
   }
 
   if (NULL == tpriv) {
-    usbi_err (TRANSFER_CTX(transfer), "malformed request is missing transfer priv");
+    usbi_err (ctx, "malformed request is missing transfer priv");
     return LIBUSB_ERROR_INVALID_PARAM;
   }
 
-  usbi_dbg ("handling transfer completion type %s with kernel status %d", transfer_types[transfer->type], tpriv->result);
+  usbi_dbg (ctx, "handling transfer completion type %s with kernel status %d", transfer_types[transfer->type], tpriv->result);
 
   if (kIOReturnSuccess == tpriv->result || kIOReturnUnderrun == tpriv->result || kIOUSBTransactionTimeout == tpriv->result) {
     if (is_isoc && tpriv->isoc_framelist) {
@@ -2359,7 +2374,7 @@
 
   usbi_mutex_lock(&darwin_cached_devices_lock);
   (*(dpriv->device))->Release(dpriv->device);
-  dpriv->device = darwin_device_from_service (dpriv->service);
+  dpriv->device = darwin_device_from_service (HANDLE_CTX (dev_handle), dpriv->service);
   if (!dpriv->device) {
     err = LIBUSB_ERROR_NO_DEVICE;
   } else {
@@ -2377,6 +2392,7 @@
   struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev);
   IOReturn kresult;
   enum libusb_error err;
+  struct libusb_context *ctx = HANDLE_CTX (dev_handle);
 
   if (HAS_CAPTURE_DEVICE()) {
   } else {
@@ -2384,17 +2400,17 @@
   }
 
   if (dpriv->capture_count == 0) {
-    usbi_dbg ("attempting to detach kernel driver from device");
+    usbi_dbg (ctx, "attempting to detach kernel driver from device");
 
     if (!darwin_has_capture_entitlements ()) {
-      usbi_info (HANDLE_CTX (dev_handle), "no capture entitlements. can not detach the kernel driver for this device");
+      usbi_info (ctx, "no capture entitlements. can not detach the kernel driver for this device");
       return LIBUSB_ERROR_NOT_SUPPORTED;
     }
 
     /* request authorization */
     kresult = IOServiceAuthorize (dpriv->service, kIOServiceInteractionAllowed);
     if (kresult != kIOReturnSuccess) {
-      usbi_warn (HANDLE_CTX (dev_handle), "IOServiceAuthorize: %s", darwin_error_str(kresult));
+      usbi_warn (ctx, "IOServiceAuthorize: %s", darwin_error_str(kresult));
       return darwin_to_libusb (kresult);
     }
 
@@ -2429,7 +2445,7 @@
     return LIBUSB_SUCCESS;
   }
 
-  usbi_dbg ("reenumerating device for kernel driver attach");
+  usbi_dbg (HANDLE_CTX (dev_handle), "reenumerating device for kernel driver attach");
 
   /* reset device to attach kernel drivers */
   return darwin_reenumerate_device (dev_handle, false);
diff --git a/libusb/os/events_posix.c b/libusb/os/events_posix.c
index b74189b..715a2d5 100644
--- a/libusb/os/events_posix.c
+++ b/libusb/os/events_posix.c
@@ -222,9 +222,9 @@
 	usbi_nfds_t nfds = (usbi_nfds_t)ctx->event_data_cnt;
 	int internal_fds, num_ready;
 
-	usbi_dbg("poll() %u fds with timeout in %dms", (unsigned int)nfds, timeout_ms);
+	usbi_dbg(ctx, "poll() %u fds with timeout in %dms", (unsigned int)nfds, timeout_ms);
 	num_ready = poll(fds, nfds, timeout_ms);
-	usbi_dbg("poll() returned %d", num_ready);
+	usbi_dbg(ctx, "poll() returned %d", num_ready);
 	if (num_ready == 0) {
 		if (usbi_using_timer(ctx))
 			goto done;
@@ -279,7 +279,7 @@
 					continue;
 				/* pollfd was removed between the creation of the fds array and
 				 * here. remove triggered revent as it is no longer relevant. */
-				usbi_dbg("fd %d was removed, ignoring raised events", fds[n].fd);
+				usbi_dbg(ctx, "fd %d was removed, ignoring raised events", fds[n].fd);
 				fds[n].revents = 0;
 				num_ready--;
 				break;
diff --git a/libusb/os/events_windows.c b/libusb/os/events_windows.c
index 81d8b87..f22bebc 100644
--- a/libusb/os/events_windows.c
+++ b/libusb/os/events_windows.c
@@ -171,9 +171,9 @@
 	DWORD num_handles = (DWORD)ctx->event_data_cnt;
 	DWORD result;
 
-	usbi_dbg("WaitForMultipleObjects() for %lu HANDLEs with timeout in %dms", ULONG_CAST(num_handles), timeout_ms);
+	usbi_dbg(ctx, "WaitForMultipleObjects() for %lu HANDLEs with timeout in %dms", ULONG_CAST(num_handles), timeout_ms);
 	result = WaitForMultipleObjects(num_handles, handles, FALSE, (DWORD)timeout_ms);
-	usbi_dbg("WaitForMultipleObjects() returned %lu", ULONG_CAST(result));
+	usbi_dbg(ctx, "WaitForMultipleObjects() returned %lu", ULONG_CAST(result));
 	if (result == WAIT_TIMEOUT) {
 		if (usbi_using_timer(ctx))
 			goto done;
diff --git a/libusb/os/haiku_pollfs.cpp b/libusb/os/haiku_pollfs.cpp
index cb4fda8..b85edf7 100644
--- a/libusb/os/haiku_pollfs.cpp
+++ b/libusb/os/haiku_pollfs.cpp
@@ -100,14 +100,14 @@
 			for_each_context(ctx) {
 				struct libusb_device *dev = usbi_get_device_by_session_id(ctx, session_id);
 				if (dev) {
-					usbi_dbg("using previously allocated device with location %lu", session_id);
+					usbi_dbg(NULL, "using previously allocated device with location %lu", session_id);
 					libusb_unref_device(dev);
 					continue;
 				}
-				usbi_dbg("allocating new device with location %lu", session_id);
+				usbi_dbg(NULL, "allocating new device with location %lu", session_id);
 				dev = usbi_alloc_device(ctx, session_id);
 				if (!dev) {
-					usbi_dbg("device allocation failed");
+					usbi_dbg(NULL, "device allocation failed");
 					continue;
 				}
 				*((USBDevice **)usbi_get_device_priv(dev)) = fDevice;
@@ -134,7 +134,7 @@
 				usbi_localize_device_descriptor(&dev->device_descriptor);
 
 				if (usbi_sanitize_device(dev) < 0) {
-					usbi_dbg("device sanitization failed");
+					usbi_dbg(NULL, "device sanitization failed");
 					libusb_unref_device(dev);
 					continue;
 				}
@@ -178,7 +178,7 @@
 				usbi_disconnect_device(dev);
 				libusb_unref_device(dev);
 			} else {
-				usbi_dbg("device with location %lu not found", session_id);
+				usbi_dbg(ctx, "device with location %lu not found", session_id);
 			}
 		}
 		usbi_mutex_static_unlock(&active_contexts_lock);
diff --git a/libusb/os/haiku_usb_backend.cpp b/libusb/os/haiku_usb_backend.cpp
index 8bbf3e0..e1d7efe 100644
--- a/libusb/os/haiku_usb_backend.cpp
+++ b/libusb/os/haiku_usb_backend.cpp
@@ -296,7 +296,7 @@
 		return _errno_to_libusb(command.alternate.status);
 	}
 	if (command.alternate.alternate_info == (uint32)alt) {
-		usbi_dbg("Setting alternate interface successful");
+		usbi_dbg(NULL, "Setting alternate interface successful");
 		return LIBUSB_SUCCESS;
 	}
 	command.alternate.alternate_info = alt;
@@ -305,7 +305,7 @@
 		usbi_err(NULL, "Error setting alternate interface");
 		return _errno_to_libusb(command.alternate.status);
 	}
-	usbi_dbg("Setting alternate interface successful");
+	usbi_dbg(NULL, "Setting alternate interface successful");
 	return LIBUSB_SUCCESS;
 }
 
diff --git a/libusb/os/linux_netlink.c b/libusb/os/linux_netlink.c
index fc0dbfc..899084f 100644
--- a/libusb/os/linux_netlink.c
+++ b/libusb/os/linux_netlink.c
@@ -99,7 +99,7 @@
 
 	linux_netlink_socket = socket(PF_NETLINK, socktype, NETLINK_KOBJECT_UEVENT);
 	if (linux_netlink_socket == -1 && errno == EINVAL) {
-		usbi_dbg("failed to create netlink socket of type %d, attempting SOCK_RAW", socktype);
+		usbi_dbg(NULL, "failed to create netlink socket of type %d, attempting SOCK_RAW", socktype);
 		socktype = SOCK_RAW;
 		linux_netlink_socket = socket(PF_NETLINK, socktype, NETLINK_KOBJECT_UEVENT);
 	}
@@ -204,7 +204,7 @@
 	} else if (strcmp(tmp, "remove") == 0) {
 		*detached = 1;
 	} else if (strcmp(tmp, "add") != 0) {
-		usbi_dbg("unknown device action %s", tmp);
+		usbi_dbg(NULL, "unknown device action %s", tmp);
 		return -1;
 	}
 
@@ -311,20 +311,20 @@
 	}
 
 	if (sa_nl.nl_groups != NL_GROUP_KERNEL || sa_nl.nl_pid != 0) {
-		usbi_dbg("ignoring netlink message from unknown group/PID (%u/%u)",
+		usbi_dbg(NULL, "ignoring netlink message from unknown group/PID (%u/%u)",
 			 (unsigned int)sa_nl.nl_groups, (unsigned int)sa_nl.nl_pid);
 		return -1;
 	}
 
 	cmsg = CMSG_FIRSTHDR(&msg);
 	if (!cmsg || cmsg->cmsg_type != SCM_CREDENTIALS) {
-		usbi_dbg("ignoring netlink message with no sender credentials");
+		usbi_dbg(NULL, "ignoring netlink message with no sender credentials");
 		return -1;
 	}
 
 	cred = (struct ucred *)CMSG_DATA(cmsg);
 	if (cred->uid != 0) {
-		usbi_dbg("ignoring netlink message with non-zero sender UID %u", (unsigned int)cred->uid);
+		usbi_dbg(NULL, "ignoring netlink message with non-zero sender UID %u", (unsigned int)cred->uid);
 		return -1;
 	}
 
@@ -332,7 +332,7 @@
 	if (r)
 		return r;
 
-	usbi_dbg("netlink hotplug found device busnum: %hhu, devaddr: %hhu, sys_name: %s, removed: %s",
+	usbi_dbg(NULL, "netlink hotplug found device busnum: %hhu, devaddr: %hhu, sys_name: %s, removed: %s",
 		 busnum, devaddr, sys_name, detached ? "yes" : "no");
 
 	/* signal device is available (or not) to all contexts */
@@ -362,7 +362,7 @@
 		usbi_warn(NULL, "failed to set hotplug event thread name, error=%d", r);
 #endif
 
-	usbi_dbg("netlink event thread entering");
+	usbi_dbg(NULL, "netlink event thread entering");
 
 	while (1) {
 		r = poll(fds, 2, -1);
@@ -384,7 +384,7 @@
 		}
 	}
 
-	usbi_dbg("netlink event thread exiting");
+	usbi_dbg(NULL, "netlink event thread exiting");
 
 	return NULL;
 }
diff --git a/libusb/os/linux_udev.c b/libusb/os/linux_udev.c
index beb2f05..9ec9eb1 100644
--- a/libusb/os/linux_udev.c
+++ b/libusb/os/linux_udev.c
@@ -177,7 +177,7 @@
 		usbi_warn(NULL, "failed to set hotplug event thread name, error=%d", r);
 #endif
 
-	usbi_dbg("udev event thread entering");
+	usbi_dbg(NULL, "udev event thread entering");
 
 	while (1) {
 		r = poll(fds, 2, -1);
@@ -201,7 +201,7 @@
 		}
 	}
 
-	usbi_dbg("udev event thread exiting");
+	usbi_dbg(NULL, "udev event thread exiting");
 
 	return NULL;
 }
@@ -246,7 +246,7 @@
 			break;
 		}
 
-		usbi_dbg("udev hotplug event. action: %s.", udev_action);
+		usbi_dbg(NULL, "udev hotplug event. action: %s.", udev_action);
 
 		if (strncmp(udev_action, "add", 3) == 0) {
 			linux_hotplug_enumerate(busnum, devaddr, sys_name);
@@ -313,7 +313,7 @@
 	do {
 		udev_dev = udev_monitor_receive_device(udev_monitor);
 		if (udev_dev) {
-			usbi_dbg("Handling hotplug event from hotplug_poll");
+			usbi_dbg(NULL, "Handling hotplug event from hotplug_poll");
 			udev_hotplug_event(udev_dev);
 		}
 	} while (udev_dev);
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
index c250632..1888c92 100644
--- a/libusb/os/linux_usbfs.c
+++ b/libusb/os/linux_usbfs.c
@@ -234,11 +234,11 @@
 	if (sscanf(name, "usbdev%d.%d", &busnum, &devnum) != 2)
 		return 0;
 	if (busnum < 0 || busnum > UINT8_MAX || devnum < 0 || devnum > UINT8_MAX) {
-		usbi_dbg("invalid usbdev format '%s'", name);
+		usbi_dbg(NULL, "invalid usbdev format '%s'", name);
 		return 0;
 	}
 
-	usbi_dbg("found: %s", name);
+	usbi_dbg(NULL, "found: %s", name);
 	if (bus_p)
 		*bus_p = (uint8_t)busnum;
 	if (dev_p)
@@ -323,7 +323,7 @@
 	if (atoms < 3)
 		ver->sublevel = -1;
 
-	usbi_dbg("reported kernel version is %s", uts.release);
+	usbi_dbg(ctx, "reported kernel version is %s", uts.release);
 
 	return 0;
 }
@@ -371,7 +371,7 @@
 		return LIBUSB_ERROR_OTHER;
 	}
 
-	usbi_dbg("found usbfs at %s", usbfs_path);
+	usbi_dbg(ctx, "found usbfs at %s", usbfs_path);
 
 	if (!max_iso_packet_len) {
 		if (kernel_version_ge(&kversion, 5, 2, 0))
@@ -382,14 +382,14 @@
 			max_iso_packet_len = 8192;
 	}
 
-	usbi_dbg("max iso packet length is (likely) %u bytes", max_iso_packet_len);
+	usbi_dbg(ctx, "max iso packet length is (likely) %u bytes", max_iso_packet_len);
 
 	if (sysfs_available == -1) {
 		struct statfs statfsbuf;
 
 		r = statfs(SYSFS_MOUNT_PATH, &statfsbuf);
 		if (r == 0 && statfsbuf.f_type == SYSFS_MAGIC) {
-			usbi_dbg("sysfs is available");
+			usbi_dbg(ctx, "sysfs is available");
 			sysfs_available = 1;
 		} else {
 			usbi_warn(ctx, "sysfs not mounted");
@@ -441,7 +441,7 @@
 
 	if (option == LIBUSB_OPTION_NO_DEVICE_DISCOVERY ||
 	    option == LIBUSB_OPTION_WEAK_AUTHORITY) {
-		usbi_dbg("no enumeration will be performed");
+		usbi_dbg(ctx, "no enumeration will be performed");
 		no_enumeration = 1;
 		return LIBUSB_SUCCESS;
 	}
@@ -589,7 +589,7 @@
 	int sysfs_val;
 	int r;
 
-	usbi_dbg("getting address for device: %s detached: %d", sys_name, detached);
+	usbi_dbg(ctx, "getting address for device: %s detached: %d", sys_name, detached);
 	/* can't use sysfs to read the bus and device number if the
 	 * device has been detached */
 	if (!sysfs_available || detached || !sys_name) {
@@ -618,7 +618,7 @@
 		return LIBUSB_SUCCESS;
 	}
 
-	usbi_dbg("scan %s", sys_name);
+	usbi_dbg(ctx, "scan %s", sys_name);
 
 	r = read_sysfs_attr(ctx, sys_name, "busnum", UINT8_MAX, &sysfs_val);
 	if (r < 0)
@@ -630,7 +630,7 @@
 		return r;
 	*devaddr = (uint8_t)sysfs_val;
 
-	usbi_dbg("bus=%u dev=%u", *busnum, *devaddr);
+	usbi_dbg(ctx, "bus=%u dev=%u", *busnum, *devaddr);
 
 	return LIBUSB_SUCCESS;
 }
@@ -1073,14 +1073,14 @@
 	usbi_mutex_unlock(&ctx->usb_devs_lock);
 
 	if (!dev->parent_dev && add_parent) {
-		usbi_dbg("parent_dev %s not enumerated yet, enumerating now",
+		usbi_dbg(ctx, "parent_dev %s not enumerated yet, enumerating now",
 			 parent_sysfs_dir);
 		sysfs_scan_device(ctx, parent_sysfs_dir);
 		add_parent = 0;
 		goto retry;
 	}
 
-	usbi_dbg("dev %p (%s) has parent %p (%s) port %u", dev, sysfs_dir,
+	usbi_dbg(ctx, "dev %p (%s) has parent %p (%s) port %u", dev, sysfs_dir,
 		 dev->parent_dev, parent_sysfs_dir, dev->port_number);
 
 	free(parent_sysfs_dir);
@@ -1099,17 +1099,17 @@
 	 * will be reused. instead we should add a simple sysfs attribute with
 	 * a session ID. */
 	session_id = busnum << 8 | devaddr;
-	usbi_dbg("busnum %u devaddr %u session_id %lu", busnum, devaddr, session_id);
+	usbi_dbg(ctx, "busnum %u devaddr %u session_id %lu", busnum, devaddr, session_id);
 
 	dev = usbi_get_device_by_session_id(ctx, session_id);
 	if (dev) {
 		/* device already exists in the context */
-		usbi_dbg("session_id %lu already exists", session_id);
+		usbi_dbg(ctx, "session_id %lu already exists", session_id);
 		libusb_unref_device(dev);
 		return LIBUSB_SUCCESS;
 	}
 
-	usbi_dbg("allocating new device for %u/%u (session %lu)",
+	usbi_dbg(ctx, "allocating new device for %u/%u (session %lu)",
 		 busnum, devaddr, session_id);
 	dev = usbi_alloc_device(ctx, session_id);
 	if (!dev)
@@ -1158,7 +1158,7 @@
 			usbi_disconnect_device(dev);
 			libusb_unref_device(dev);
 		} else {
-			usbi_dbg("device not found for session %lx", session_id);
+			usbi_dbg(ctx, "device not found for session %lx", session_id);
 		}
 	}
 	usbi_mutex_static_unlock(&active_contexts_lock);
@@ -1190,7 +1190,7 @@
 	int r = LIBUSB_ERROR_IO;
 
 	sprintf(dirpath, USB_DEVTMPFS_PATH "/%03u", busnum);
-	usbi_dbg("%s", dirpath);
+	usbi_dbg(ctx, "%s", dirpath);
 	dir = opendir(dirpath);
 	if (!dir) {
 		usbi_err(ctx, "opendir '%s' failed, errno=%d", dirpath, errno);
@@ -1206,12 +1206,12 @@
 			continue;
 
 		if (!parse_u8(entry->d_name, &devaddr)) {
-			usbi_dbg("unknown dir entry %s", entry->d_name);
+			usbi_dbg(ctx, "unknown dir entry %s", entry->d_name);
 			continue;
 		}
 
 		if (linux_enumerate_device(ctx, busnum, devaddr, NULL)) {
-			usbi_dbg("failed to enumerate dir entry %s", entry->d_name);
+			usbi_dbg(ctx, "failed to enumerate dir entry %s", entry->d_name);
 			continue;
 		}
 
@@ -1249,12 +1249,12 @@
 
 			r = linux_enumerate_device(ctx, busnum, devaddr, NULL);
 			if (r < 0) {
-				usbi_dbg("failed to enumerate dir entry %s", entry->d_name);
+				usbi_dbg(ctx, "failed to enumerate dir entry %s", entry->d_name);
 				continue;
 			}
 		} else {
 			if (!parse_u8(entry->d_name, &busnum)) {
-				usbi_dbg("unknown dir entry %s", entry->d_name);
+				usbi_dbg(ctx, "unknown dir entry %s", entry->d_name);
 				continue;
 			}
 
@@ -1289,7 +1289,7 @@
 		num_devices++;
 
 		if (sysfs_scan_device(ctx, entry->d_name)) {
-			usbi_dbg("failed to enumerate dir entry %s", entry->d_name);
+			usbi_dbg(ctx, "failed to enumerate dir entry %s", entry->d_name);
 			continue;
 		}
 
@@ -1329,7 +1329,7 @@
 	r = ioctl(fd, IOCTL_USBFS_GET_CAPABILITIES, &hpriv->caps);
 	if (r < 0) {
 		if (errno == ENOTTY)
-			usbi_dbg("getcap not available");
+			usbi_dbg(HANDLE_CTX(handle), "getcap not available");
 		else
 			usbi_err(HANDLE_CTX(handle), "getcap failed, errno=%d", errno);
 		hpriv->caps = USBFS_CAP_BULK_CONTINUATION;
@@ -1363,7 +1363,7 @@
 
 	/* Session id is unused as we do not add the device to the list of
 	 * connected devices. */
-	usbi_dbg("allocating new device for fd %d", fd);
+	usbi_dbg(ctx, "allocating new device for fd %d", fd);
 	dev = usbi_alloc_device(ctx, 0);
 	if (!dev)
 		return LIBUSB_ERROR_NO_MEM;
@@ -1399,7 +1399,7 @@
 			 * hasn't processed remove event yet */
 			usbi_mutex_static_lock(&linux_hotplug_lock);
 			if (usbi_atomic_load(&handle->dev->attached)) {
-				usbi_dbg("open failed with no device, but device still attached");
+				usbi_dbg(HANDLE_CTX(handle), "open failed with no device, but device still attached");
 				linux_device_disconnected(handle->dev->bus_number,
 							  handle->dev->device_address);
 			}
@@ -1869,11 +1869,11 @@
 			continue;
 
 		if (errno == EINVAL) {
-			usbi_dbg("URB not found --> assuming ready to be reaped");
+			usbi_dbg(TRANSFER_CTX(transfer), "URB not found --> assuming ready to be reaped");
 			if (i == (last_plus_one - 1))
 				ret = LIBUSB_ERROR_NOT_FOUND;
 		} else if (errno == ENODEV) {
-			usbi_dbg("Device not found for URB --> assuming ready to be reaped");
+			usbi_dbg(TRANSFER_CTX(transfer), "Device not found for URB --> assuming ready to be reaped");
 			ret = LIBUSB_ERROR_NO_DEVICE;
 		} else {
 			usbi_warn(TRANSFER_CTX(transfer), "unrecognised discard errno %d", errno);
@@ -1964,7 +1964,7 @@
 		last_urb_partial = 1;
 		num_urbs++;
 	}
-	usbi_dbg("need %d urbs for new transfer with length %d", num_urbs, transfer->length);
+	usbi_dbg(TRANSFER_CTX(transfer), "need %d urbs for new transfer with length %d", num_urbs, transfer->length);
 	urbs = calloc(num_urbs, sizeof(*urbs));
 	if (!urbs)
 		return LIBUSB_ERROR_NO_MEM;
@@ -2029,7 +2029,7 @@
 		/* if the first URB submission fails, we can simply free up and
 		 * return failure immediately. */
 		if (i == 0) {
-			usbi_dbg("first URB failed, easy peasy");
+			usbi_dbg(TRANSFER_CTX(transfer), "first URB failed, easy peasy");
 			free(urbs);
 			tpriv->urbs = NULL;
 			return r;
@@ -2063,7 +2063,7 @@
 
 		discard_urbs(itransfer, 0, i);
 
-		usbi_dbg("reporting successful submission but waiting for %d "
+		usbi_dbg(TRANSFER_CTX(transfer), "reporting successful submission but waiting for %d "
 			 "discards before reporting error", i);
 		return 0;
 	}
@@ -2114,7 +2114,7 @@
 	/* usbfs limits the number of iso packets per URB */
 	num_urbs = (num_packets + (MAX_ISO_PACKETS_PER_URB - 1)) / MAX_ISO_PACKETS_PER_URB;
 
-	usbi_dbg("need %d urbs for new transfer with length %d", num_urbs, transfer->length);
+	usbi_dbg(TRANSFER_CTX(transfer), "need %d urbs for new transfer with length %d", num_urbs, transfer->length);
 
 	urbs = calloc(num_urbs, sizeof(*urbs));
 	if (!urbs)
@@ -2185,7 +2185,7 @@
 		/* if the first URB submission fails, we can simply free up and
 		 * return failure immediately. */
 		if (i == 0) {
-			usbi_dbg("first URB failed, easy peasy");
+			usbi_dbg(TRANSFER_CTX(transfer), "first URB failed, easy peasy");
 			free_iso_urbs(tpriv);
 			return r;
 		}
@@ -2210,7 +2210,7 @@
 		tpriv->num_retired = num_urbs - i;
 		discard_urbs(itransfer, 0, i);
 
-		usbi_dbg("reporting successful submission but waiting for %d "
+		usbi_dbg(TRANSFER_CTX(transfer), "reporting successful submission but waiting for %d "
 			 "discards before reporting error", i);
 		return 0;
 	}
@@ -2340,14 +2340,14 @@
 	int urb_idx = urb - tpriv->urbs;
 
 	usbi_mutex_lock(&itransfer->lock);
-	usbi_dbg("handling completion status %d of bulk urb %d/%d", urb->status,
+	usbi_dbg(TRANSFER_CTX(transfer), "handling completion status %d of bulk urb %d/%d", urb->status,
 		 urb_idx + 1, tpriv->num_urbs);
 
 	tpriv->num_retired++;
 
 	if (tpriv->reap_action != NORMAL) {
 		/* cancelled, submit_fail, or completed early */
-		usbi_dbg("abnormal reap: urb status %d", urb->status);
+		usbi_dbg(TRANSFER_CTX(transfer), "abnormal reap: urb status %d", urb->status);
 
 		/* even though we're in the process of cancelling, it's possible that
 		 * we may receive some data in these URBs that we don't want to lose.
@@ -2368,9 +2368,9 @@
 		if (urb->actual_length > 0) {
 			unsigned char *target = transfer->buffer + itransfer->transferred;
 
-			usbi_dbg("received %d bytes of surplus data", urb->actual_length);
+			usbi_dbg(TRANSFER_CTX(transfer), "received %d bytes of surplus data", urb->actual_length);
 			if (urb->buffer != target) {
-				usbi_dbg("moving surplus data from offset %zu to offset %zu",
+				usbi_dbg(TRANSFER_CTX(transfer), "moving surplus data from offset %zu to offset %zu",
 					 (unsigned char *)urb->buffer - transfer->buffer,
 					 target - transfer->buffer);
 				memmove(target, urb->buffer, urb->actual_length);
@@ -2379,7 +2379,7 @@
 		}
 
 		if (tpriv->num_retired == tpriv->num_urbs) {
-			usbi_dbg("abnormal reap: last URB handled, reporting");
+			usbi_dbg(TRANSFER_CTX(transfer), "abnormal reap: last URB handled, reporting");
 			if (tpriv->reap_action != COMPLETED_EARLY &&
 			    tpriv->reap_status == LIBUSB_TRANSFER_COMPLETED)
 				tpriv->reap_status = LIBUSB_TRANSFER_ERROR;
@@ -2403,17 +2403,17 @@
 		break;
 	case -ENODEV:
 	case -ESHUTDOWN:
-		usbi_dbg("device removed");
+		usbi_dbg(TRANSFER_CTX(transfer), "device removed");
 		tpriv->reap_status = LIBUSB_TRANSFER_NO_DEVICE;
 		goto cancel_remaining;
 	case -EPIPE:
-		usbi_dbg("detected endpoint stall");
+		usbi_dbg(TRANSFER_CTX(transfer), "detected endpoint stall");
 		if (tpriv->reap_status == LIBUSB_TRANSFER_COMPLETED)
 			tpriv->reap_status = LIBUSB_TRANSFER_STALL;
 		goto cancel_remaining;
 	case -EOVERFLOW:
 		/* overflow can only ever occur in the last urb */
-		usbi_dbg("overflow, actual_length=%d", urb->actual_length);
+		usbi_dbg(TRANSFER_CTX(transfer), "overflow, actual_length=%d", urb->actual_length);
 		if (tpriv->reap_status == LIBUSB_TRANSFER_COMPLETED)
 			tpriv->reap_status = LIBUSB_TRANSFER_OVERFLOW;
 		goto completed;
@@ -2422,7 +2422,7 @@
 	case -EILSEQ:
 	case -ECOMM:
 	case -ENOSR:
-		usbi_dbg("low-level bus error %d", urb->status);
+		usbi_dbg(TRANSFER_CTX(transfer), "low-level bus error %d", urb->status);
 		tpriv->reap_action = ERROR;
 		goto cancel_remaining;
 	default:
@@ -2434,10 +2434,10 @@
 	/* if we've reaped all urbs or we got less data than requested then we're
 	 * done */
 	if (tpriv->num_retired == tpriv->num_urbs) {
-		usbi_dbg("all URBs in transfer reaped --> complete!");
+		usbi_dbg(TRANSFER_CTX(transfer), "all URBs in transfer reaped --> complete!");
 		goto completed;
 	} else if (urb->actual_length < urb->buffer_length) {
-		usbi_dbg("short transfer %d/%d --> complete!",
+		usbi_dbg(TRANSFER_CTX(transfer), "short transfer %d/%d --> complete!",
 			 urb->actual_length, urb->buffer_length);
 		if (tpriv->reap_action == NORMAL)
 			tpriv->reap_action = COMPLETED_EARLY;
@@ -2493,7 +2493,7 @@
 		return LIBUSB_ERROR_NOT_FOUND;
 	}
 
-	usbi_dbg("handling completion status %d of iso urb %d/%d", urb->status,
+	usbi_dbg(TRANSFER_CTX(transfer), "handling completion status %d of iso urb %d/%d", urb->status,
 		 urb_idx, num_urbs);
 
 	/* copy isochronous results back in */
@@ -2512,15 +2512,15 @@
 			break;
 		case -ENODEV:
 		case -ESHUTDOWN:
-			usbi_dbg("packet %d - device removed", i);
+			usbi_dbg(TRANSFER_CTX(transfer), "packet %d - device removed", i);
 			lib_desc->status = LIBUSB_TRANSFER_NO_DEVICE;
 			break;
 		case -EPIPE:
-			usbi_dbg("packet %d - detected endpoint stall", i);
+			usbi_dbg(TRANSFER_CTX(transfer), "packet %d - detected endpoint stall", i);
 			lib_desc->status = LIBUSB_TRANSFER_STALL;
 			break;
 		case -EOVERFLOW:
-			usbi_dbg("packet %d - overflow error", i);
+			usbi_dbg(TRANSFER_CTX(transfer), "packet %d - overflow error", i);
 			lib_desc->status = LIBUSB_TRANSFER_OVERFLOW;
 			break;
 		case -ETIME:
@@ -2529,7 +2529,7 @@
 		case -ECOMM:
 		case -ENOSR:
 		case -EXDEV:
-			usbi_dbg("packet %d - low-level USB error %d", i, urb_desc->status);
+			usbi_dbg(TRANSFER_CTX(transfer), "packet %d - low-level USB error %d", i, urb_desc->status);
 			lib_desc->status = LIBUSB_TRANSFER_ERROR;
 			break;
 		default:
@@ -2544,10 +2544,10 @@
 	tpriv->num_retired++;
 
 	if (tpriv->reap_action != NORMAL) { /* cancelled or submit_fail */
-		usbi_dbg("CANCEL: urb status %d", urb->status);
+		usbi_dbg(TRANSFER_CTX(transfer), "CANCEL: urb status %d", urb->status);
 
 		if (tpriv->num_retired == num_urbs) {
-			usbi_dbg("CANCEL: last URB handled, reporting");
+			usbi_dbg(TRANSFER_CTX(transfer), "CANCEL: last URB handled, reporting");
 			free_iso_urbs(tpriv);
 			if (tpriv->reap_action == CANCELLED) {
 				usbi_mutex_unlock(&itransfer->lock);
@@ -2567,7 +2567,7 @@
 	case -ECONNRESET:
 		break;
 	case -ESHUTDOWN:
-		usbi_dbg("device removed");
+		usbi_dbg(TRANSFER_CTX(transfer), "device removed");
 		status = LIBUSB_TRANSFER_NO_DEVICE;
 		break;
 	default:
@@ -2578,7 +2578,7 @@
 
 	/* if we've reaped all urbs then we're done */
 	if (tpriv->num_retired == num_urbs) {
-		usbi_dbg("all URBs in transfer reaped --> complete!");
+		usbi_dbg(TRANSFER_CTX(transfer), "all URBs in transfer reaped --> complete!");
 		free_iso_urbs(tpriv);
 		usbi_mutex_unlock(&itransfer->lock);
 		return usbi_handle_transfer_completion(itransfer, status);
@@ -2596,7 +2596,7 @@
 	int status;
 
 	usbi_mutex_lock(&itransfer->lock);
-	usbi_dbg("handling completion status %d", urb->status);
+	usbi_dbg(ITRANSFER_CTX(itransfer), "handling completion status %d", urb->status);
 
 	itransfer->transferred += urb->actual_length;
 
@@ -2619,15 +2619,15 @@
 		break;
 	case -ENODEV:
 	case -ESHUTDOWN:
-		usbi_dbg("device removed");
+		usbi_dbg(ITRANSFER_CTX(itransfer), "device removed");
 		status = LIBUSB_TRANSFER_NO_DEVICE;
 		break;
 	case -EPIPE:
-		usbi_dbg("unsupported control request");
+		usbi_dbg(ITRANSFER_CTX(itransfer), "unsupported control request");
 		status = LIBUSB_TRANSFER_STALL;
 		break;
 	case -EOVERFLOW:
-		usbi_dbg("overflow, actual_length=%d", urb->actual_length);
+		usbi_dbg(ITRANSFER_CTX(itransfer), "overflow, actual_length=%d", urb->actual_length);
 		status = LIBUSB_TRANSFER_OVERFLOW;
 		break;
 	case -ETIME:
@@ -2635,7 +2635,7 @@
 	case -EILSEQ:
 	case -ECOMM:
 	case -ENOSR:
-		usbi_dbg("low-level bus error %d", urb->status);
+		usbi_dbg(ITRANSFER_CTX(itransfer), "low-level bus error %d", urb->status);
 		status = LIBUSB_TRANSFER_ERROR;
 		break;
 	default:
@@ -2672,7 +2672,7 @@
 	itransfer = urb->usercontext;
 	transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
 
-	usbi_dbg("urb type=%u status=%d transferred=%d", urb->type, urb->status, urb->actual_length);
+	usbi_dbg(HANDLE_CTX(handle), "urb type=%u status=%d transferred=%d", urb->type, urb->status, urb->actual_length);
 
 	switch (transfer->type) {
 	case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
diff --git a/libusb/os/netbsd_usb.c b/libusb/os/netbsd_usb.c
index 7a36209..d63a048 100644
--- a/libusb/os/netbsd_usb.c
+++ b/libusb/os/netbsd_usb.c
@@ -122,7 +122,7 @@
 	char devnode[16];
 	int fd, err, i;
 
-	usbi_dbg(" ");
+	usbi_dbg(ctx, " ");
 
 	/* Only ugen(4) is supported */
 	for (i = 0; i < USB_MAX_DEVICES; i++) {
@@ -205,7 +205,7 @@
 	for (i = 0; i < USB_MAX_ENDPOINTS; i++)
 		hpriv->endpoints[i] = -1;
 
-	usbi_dbg("open %s: fd %d", dpriv->devnode, dpriv->fd);
+	usbi_dbg(HANDLE_CTX(handle), "open %s: fd %d", dpriv->devnode, dpriv->fd);
 
 	return (LIBUSB_SUCCESS);
 }
@@ -215,7 +215,7 @@
 {
 	struct device_priv *dpriv = usbi_get_device_priv(handle->dev);
 
-	usbi_dbg("close: fd %d", dpriv->fd);
+	usbi_dbg(HANDLE_CTX(handle), "close: fd %d", dpriv->fd);
 
 	close(dpriv->fd);
 	dpriv->fd = -1;
@@ -229,7 +229,7 @@
 
 	len = MIN(len, (size_t)UGETW(dpriv->cdesc->wTotalLength));
 
-	usbi_dbg("len %zu", len);
+	usbi_dbg(DEVICE_CTX(dev), "len %zu", len);
 
 	memcpy(buf, dpriv->cdesc, len);
 
@@ -244,7 +244,7 @@
 	struct usb_full_desc ufd;
 	int fd, err;
 
-	usbi_dbg("index %u, len %zu", idx, len);
+	usbi_dbg(DEVICE_CTX(dev), "index %u, len %zu", idx, len);
 
 	/* A config descriptor may be requested before opening the device */
 	if (dpriv->fd >= 0) {
@@ -278,12 +278,12 @@
 	struct device_priv *dpriv = usbi_get_device_priv(handle->dev);
 	int tmp;
 
-	usbi_dbg(" ");
+	usbi_dbg(HANDLE_CTX(handle), " ");
 
 	if (ioctl(dpriv->fd, USB_GET_CONFIG, &tmp) < 0)
 		return _errno_to_libusb(errno);
 
-	usbi_dbg("configuration %d", tmp);
+	usbi_dbg(HANDLE_CTX(handle), "configuration %d", tmp);
 	*config = (uint8_t)tmp;
 
 	return (LIBUSB_SUCCESS);
@@ -294,7 +294,7 @@
 {
 	struct device_priv *dpriv = usbi_get_device_priv(handle->dev);
 
-	usbi_dbg("configuration %d", config);
+	usbi_dbg(HANDLE_CTX(handle), "configuration %d", config);
 
 	if (ioctl(dpriv->fd, USB_SET_CONFIG, &config) < 0)
 		return _errno_to_libusb(errno);
@@ -338,7 +338,7 @@
 	struct device_priv *dpriv = usbi_get_device_priv(handle->dev);
 	struct usb_alt_interface intf;
 
-	usbi_dbg("iface %u, setting %u", iface, altsetting);
+	usbi_dbg(HANDLE_CTX(handle), "iface %u, setting %u", iface, altsetting);
 
 	memset(&intf, 0, sizeof(intf));
 
@@ -357,7 +357,7 @@
 	struct device_priv *dpriv = usbi_get_device_priv(handle->dev);
 	struct usb_ctl_request req;
 
-	usbi_dbg(" ");
+	usbi_dbg(HANDLE_CTX(handle), " ");
 
 	req.ucr_request.bmRequestType = UT_WRITE_ENDPOINT;
 	req.ucr_request.bRequest = UR_CLEAR_FEATURE;
@@ -376,7 +376,7 @@
 {
 	struct device_priv *dpriv = usbi_get_device_priv(dev);
 
-	usbi_dbg(" ");
+	usbi_dbg(DEVICE_CTX(dev), " ");
 
 	free(dpriv->cdesc);
 }
@@ -387,7 +387,7 @@
 	struct libusb_transfer *transfer;
 	int err = 0;
 
-	usbi_dbg(" ");
+	usbi_dbg(ITRANSFER_CTX(itransfer), " ");
 
 	transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
 
@@ -430,7 +430,7 @@
 {
 	UNUSED(itransfer);
 
-	usbi_dbg(" ");
+	usbi_dbg(ITRANSFER_CTX(itransfer), " ");
 
 	return (LIBUSB_ERROR_NOT_SUPPORTED);
 }
@@ -458,7 +458,7 @@
 		return (LIBUSB_ERROR_TIMEOUT);
 	}
 
-	usbi_dbg("error: %s", strerror(err));
+	usbi_dbg(NULL, "error: %s", strerror(err));
 
 	return (LIBUSB_ERROR_OTHER);
 }
@@ -472,14 +472,14 @@
 	void *buf;
 	int len;
 
-	usbi_dbg("fd %d", fd);
+	usbi_dbg(DEVICE_CTX(dev), "fd %d", fd);
 
 	ucd.ucd_config_index = USB_CURRENT_CONFIG_INDEX;
 
 	if ((ioctl(fd, USB_GET_CONFIG_DESC, &ucd)) < 0)
 		return _errno_to_libusb(errno);
 
-	usbi_dbg("active bLength %d", ucd.ucd_desc.bLength);
+	usbi_dbg(DEVICE_CTX(dev), "active bLength %d", ucd.ucd_desc.bLength);
 
 	len = UGETW(ucd.ucd_desc.wTotalLength);
 	buf = malloc((size_t)len);
@@ -490,7 +490,7 @@
 	ufd.ufd_size = len;
 	ufd.ufd_data = buf;
 
-	usbi_dbg("index %d, len %d", ufd.ufd_config_index, len);
+	usbi_dbg(DEVICE_CTX(dev), "index %d, len %d", ufd.ufd_config_index, len);
 
 	if ((ioctl(fd, USB_GET_FULL_DESC, &ufd)) < 0) {
 		free(buf);
@@ -516,7 +516,7 @@
 	dpriv = usbi_get_device_priv(transfer->dev_handle->dev);
 	setup = (struct libusb_control_setup *)transfer->buffer;
 
-	usbi_dbg("type %d request %d value %d index %d length %d timeout %d",
+	usbi_dbg(ITRANSFER_CTX(itransfer), "type %d request %d value %d index %d length %d timeout %d",
 	    setup->bmRequestType, setup->bRequest,
 	    libusb_le16_to_cpu(setup->wValue),
 	    libusb_le16_to_cpu(setup->wIndex),
@@ -541,7 +541,7 @@
 
 	itransfer->transferred = req.ucr_actlen;
 
-	usbi_dbg("transferred %d", itransfer->transferred);
+	usbi_dbg(ITRANSFER_CTX(itransfer), "transferred %d", itransfer->transferred);
 
 	return (0);
 }
@@ -561,7 +561,7 @@
 	endpt = UE_GET_ADDR(transfer->endpoint);
 	mode = IS_XFERIN(transfer) ? O_RDONLY : O_WRONLY;
 
-	usbi_dbg("endpoint %d mode %d", endpt, mode);
+	usbi_dbg(ITRANFER_CTX(itransfer), "endpoint %d mode %d", endpt, mode);
 
 	if (hpriv->endpoints[endpt] < 0) {
 		/* Pick the right node given the control one */
diff --git a/libusb/os/openbsd_usb.c b/libusb/os/openbsd_usb.c
index 6ba47b4..9a5c604 100644
--- a/libusb/os/openbsd_usb.c
+++ b/libusb/os/openbsd_usb.c
@@ -129,7 +129,7 @@
 	char *udevname;
 	int fd, addr, i, j;
 
-	usbi_dbg(" ");
+	usbi_dbg(ctx, " ");
 
 	for (i = 0; i < 8; i++) {
 		snprintf(busnode, sizeof(busnode), USBDEV "%d", i);
@@ -238,7 +238,7 @@
 			return _errno_to_libusb(errno);
 		dpriv->fd = fd;
 
-		usbi_dbg("open %s: fd %d", devnode, dpriv->fd);
+		usbi_dbg(HANDLE_CTX(handle), "open %s: fd %d", devnode, dpriv->fd);
 	}
 
 	return (LIBUSB_SUCCESS);
@@ -250,7 +250,7 @@
 	struct device_priv *dpriv = usbi_get_device_priv(handle->dev);
 
 	if (dpriv->devname) {
-		usbi_dbg("close: fd %d", dpriv->fd);
+		usbi_dbg(HANDLE_CTX(handle), "close: fd %d", dpriv->fd);
 
 		close(dpriv->fd);
 		dpriv->fd = -1;
@@ -265,7 +265,7 @@
 
 	len = MIN(len, (size_t)UGETW(dpriv->cdesc->wTotalLength));
 
-	usbi_dbg("len %zu", len);
+	usbi_dbg(DEVICE_CTX(dev), "len %zu", len);
 
 	memcpy(buf, dpriv->cdesc, len);
 
@@ -288,7 +288,7 @@
 	udf.udf_size = len;
 	udf.udf_data = buf;
 
-	usbi_dbg("index %d, len %zu", udf.udf_config_index, len);
+	usbi_dbg(DEVICE_CTX(dev), "index %d, len %zu", udf.udf_config_index, len);
 
 	if (ioctl(fd, USB_DEVICE_GET_FDESC, &udf) < 0) {
 		err = errno;
@@ -307,7 +307,7 @@
 
 	*config = dpriv->cdesc->bConfigurationValue;
 
-	usbi_dbg("bConfigurationValue %u", *config);
+	usbi_dbg(HANDLE_CTX(handle), "bConfigurationValue %u", *config);
 
 	return (LIBUSB_SUCCESS);
 }
@@ -320,7 +320,7 @@
 	if (dpriv->devname == NULL)
 		return (LIBUSB_ERROR_NOT_SUPPORTED);
 
-	usbi_dbg("bConfigurationValue %d", config);
+	usbi_dbg(HANDLE_CTX(handle), "bConfigurationValue %d", config);
 
 	if (ioctl(dpriv->fd, USB_SET_CONFIG, &config) < 0)
 		return _errno_to_libusb(errno);
@@ -367,7 +367,7 @@
 	if (dpriv->devname == NULL)
 		return (LIBUSB_ERROR_NOT_SUPPORTED);
 
-	usbi_dbg("iface %u, setting %u", iface, altsetting);
+	usbi_dbg(HANDLE_CTX(handle), "iface %u, setting %u", iface, altsetting);
 
 	memset(&intf, 0, sizeof(intf));
 
@@ -389,7 +389,7 @@
 	if ((fd = _bus_open(handle->dev->bus_number)) < 0)
 		return _errno_to_libusb(errno);
 
-	usbi_dbg(" ");
+	usbi_dbg(HANDLE_CTX(handle), " ");
 
 	req.ucr_addr = handle->dev->device_address;
 	req.ucr_request.bmRequestType = UT_WRITE_ENDPOINT;
@@ -413,7 +413,7 @@
 {
 	struct device_priv *dpriv = usbi_get_device_priv(dev);
 
-	usbi_dbg(" ");
+	usbi_dbg(DEVICE_CTX(dev), " ");
 
 	free(dpriv->cdesc);
 	free(dpriv->devname);
@@ -425,7 +425,7 @@
 	struct libusb_transfer *transfer;
 	int err = 0;
 
-	usbi_dbg(" ");
+	usbi_dbg(ITRANSFER_CTX(itransfer), " ");
 
 	transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
 
@@ -468,7 +468,7 @@
 {
 	UNUSED(itransfer);
 
-	usbi_dbg(" ");
+	usbi_dbg(ITRANSFER_CTX(itransfer), " ");
 
 	return (LIBUSB_ERROR_NOT_SUPPORTED);
 }
@@ -482,7 +482,7 @@
 int
 _errno_to_libusb(int err)
 {
-	usbi_dbg("error: %s (%d)", strerror(err), err);
+	usbi_dbg(NULL, "error: %s (%d)", strerror(err), err);
 
 	switch (err) {
 	case EIO:
@@ -512,7 +512,7 @@
 	if ((fd = _bus_open(dev->bus_number)) < 0)
 		return _errno_to_libusb(errno);
 
-	usbi_dbg("fd %d, addr %d", fd, dev->device_address);
+	usbi_dbg(DEVICE_CTX(dev), "fd %d, addr %d", fd, dev->device_address);
 
 	udc.udc_bus = dev->bus_number;
 	udc.udc_addr = dev->device_address;
@@ -523,7 +523,7 @@
 		return _errno_to_libusb(errno);
 	}
 
-	usbi_dbg("active bLength %d", udc.udc_desc.bLength);
+	usbi_dbg(DEVICE_CTX(dev), "active bLength %d", udc.udc_desc.bLength);
 
 	len = UGETW(udc.udc_desc.wTotalLength);
 	buf = malloc((size_t)len);
@@ -536,7 +536,7 @@
 	udf.udf_size = len;
 	udf.udf_data = buf;
 
-	usbi_dbg("index %d, len %d", udf.udf_config_index, len);
+	usbi_dbg(DEVICE_CTX(dev), "index %d, len %d", udf.udf_config_index, len);
 
 	if (ioctl(fd, USB_DEVICE_GET_FDESC, &udf) < 0) {
 		err = errno;
@@ -565,7 +565,7 @@
 	dpriv = usbi_get_device_priv(transfer->dev_handle->dev);
 	setup = (struct libusb_control_setup *)transfer->buffer;
 
-	usbi_dbg("type 0x%x request 0x%x value 0x%x index %d length %d timeout %d",
+	usbi_dbg(ITRANSFER_CTX(itransfer), "type 0x%x request 0x%x value 0x%x index %d length %d timeout %d",
 	    setup->bmRequestType, setup->bRequest,
 	    libusb_le16_to_cpu(setup->wValue),
 	    libusb_le16_to_cpu(setup->wIndex),
@@ -610,7 +610,7 @@
 
 	itransfer->transferred = req.ucr_actlen;
 
-	usbi_dbg("transferred %d", itransfer->transferred);
+	usbi_dbg(ITRANSFER_CTX(itransfer), "transferred %d", itransfer->transferred);
 
 	return (0);
 }
@@ -630,7 +630,7 @@
 	endpt = UE_GET_ADDR(transfer->endpoint);
 	mode = IS_XFERIN(transfer) ? O_RDONLY : O_WRONLY;
 
-	usbi_dbg("endpoint %d mode %d", endpt, mode);
+	usbi_dbg(TRANSFER_CTX(transfer), "endpoint %d mode %d", endpt, mode);
 
 	if (hpriv->endpoints[endpt] < 0) {
 		/* Pick the right endpoint node */
diff --git a/libusb/os/sunos_usb.c b/libusb/os/sunos_usb.c
index 46866fb..28b167f 100644
--- a/libusb/os/sunos_usb.c
+++ b/libusb/os/sunos_usb.c
@@ -90,7 +90,7 @@
 		char *content = (char *)di_devlink_content(devlink);
 		char *start = strstr(content, "/devices/");
 		start += strlen("/devices");
-		usbi_dbg("%s", start);
+		usbi_dbg(NULL, "%s", start);
 
 		/* line content must have minor node */
 		if (start == NULL ||
@@ -101,7 +101,7 @@
 
 	p = di_devlink_path(devlink);
 	q = strrchr(p, '/');
-	usbi_dbg("%s", q);
+	usbi_dbg(NULL, "%s", q);
 
 	*(larg->linkpp) = strndup(p, strlen(p) - strlen(q));
 
@@ -118,7 +118,7 @@
 	*link_path = NULL;
 	larg.linkpp = link_path;
 	if ((hdl = di_devlink_init(NULL, 0)) == NULL) {
-		usbi_dbg("di_devlink_init failure");
+		usbi_dbg(NULL, "di_devlink_init failure");
 		return (-1);
 	}
 
@@ -131,7 +131,7 @@
 	(void) di_devlink_fini(&hdl);
 
 	if (*link_path == NULL) {
-		usbi_dbg("there is no devlink for this path");
+		usbi_dbg(NULL, "there is no devlink for this path");
 		return (-1);
 	}
 
@@ -167,13 +167,13 @@
 		return (-1);
 	}
 	end++;
-	usbi_dbg("unitaddr: %s", end);
+	usbi_dbg(DEVICE_CTX(dev), "unitaddr: %s", end);
 
 	nvlist_alloc(&nvlist, NV_UNIQUE_NAME_TYPE, KM_NOSLEEP);
 	nvlist_add_int32(nvlist, "port", dev->port_number);
 	//find the hub path
 	snprintf(path_arg, sizeof(path_arg), "/devices%s:hubd", hubpath);
-	usbi_dbg("ioctl hub path: %s", path_arg);
+	usbi_dbg(DEVICE_CTX(dev), "ioctl hub path: %s", path_arg);
 
 	fd = open(path_arg, O_RDONLY);
 	if (fd < 0) {
@@ -193,15 +193,15 @@
 	iocdata.c_nodename = (char *)"hub";
 	iocdata.c_unitaddr = end;
 	iocdata.cpyout_buf = &devctl_ap_state;
-	usbi_dbg("%p, %" PRIuPTR, iocdata.nvl_user, iocdata.nvl_usersz);
+	usbi_dbg(DEVICE_CTX(dev), "%p, %" PRIuPTR, iocdata.nvl_user, iocdata.nvl_usersz);
 
 	errno = 0;
 	if (ioctl(fd, DEVCTL_AP_GETSTATE, &iocdata) == -1) {
 		usbi_err(DEVICE_CTX(dev), "ioctl failed: fd %d, cmd %x, errno %d (%s)",
 			 fd, DEVCTL_AP_GETSTATE, errno, strerror(errno));
 	} else {
-		usbi_dbg("dev rstate: %d", devctl_ap_state.ap_rstate);
-		usbi_dbg("dev ostate: %d", devctl_ap_state.ap_ostate);
+		usbi_dbg(DEVICE_CTX(dev), "dev rstate: %d", devctl_ap_state.ap_rstate);
+		usbi_dbg(DEVICE_CTX(dev), "dev ostate: %d", devctl_ap_state.ap_ostate);
 	}
 
 	errno = 0;
@@ -227,7 +227,7 @@
 
 	UNUSED(interface);
 
-	usbi_dbg("%s", dpriv->ugenpath);
+	usbi_dbg(HANDLE_CTX(dev_handle), "%s", dpriv->ugenpath);
 
 	return (dpriv->ugenpath == NULL);
 }
@@ -236,7 +236,7 @@
  * Private functions
  */
 static int _errno_to_libusb(int);
-static int sunos_usb_get_status(int fd);
+static int sunos_usb_get_status(struct libusb_context *ctx, int fd);
 
 static string_list_t *
 sunos_new_string_list(void)
@@ -358,7 +358,7 @@
 
 	dpriv = usbi_get_device_priv(dev_handle->dev);
 	snprintf(path_arg, sizeof(path_arg), "\'\"%s\"\'", dpriv->phypath);
-	usbi_dbg("%s", path_arg);
+	usbi_dbg(HANDLE_CTX(dev_handle), "%s", path_arg);
 
 	list = sunos_new_string_list();
 	if (list == NULL)
@@ -418,7 +418,7 @@
 
 	dpriv = usbi_get_device_priv(dev_handle->dev);
 	snprintf(path_arg, sizeof(path_arg), "\'\"%s\"\'", dpriv->phypath);
-	usbi_dbg("%s", path_arg);
+	usbi_dbg(HANDLE_CTX(dev_handle), "%s", path_arg);
 
 	list = sunos_new_string_list();
 	if (list == NULL)
@@ -474,7 +474,7 @@
 	proplen = di_prop_lookup_bytes(DDI_DEV_T_ANY, node,
 	    "usb-raw-cfg-descriptors", &rdata);
 	if (proplen <= 0) {
-		usbi_dbg("can't find raw config descriptors");
+		usbi_dbg(DEVICE_CTX(dev), "can't find raw config descriptors");
 
 		return (LIBUSB_ERROR_IO);
 	}
@@ -501,7 +501,7 @@
 		snprintf(match_str, sizeof(match_str), "^usb/%x.%x",
 		    dev->device_descriptor.idVendor,
 		    dev->device_descriptor.idProduct);
-		usbi_dbg("match is %s", match_str);
+		usbi_dbg(DEVICE_CTX(dev), "match is %s", match_str);
 		sunos_physpath_to_devlink(dpriv->phypath, match_str,  &dpriv->ugenpath);
 		di_devfs_path_free(phypath);
 
@@ -514,7 +514,7 @@
 	/* address */
 	n = di_prop_lookup_ints(DDI_DEV_T_ANY, node, "assigned-address", &addr);
 	if (n != 1 || *addr == 0) {
-		usbi_dbg("can't get address");
+		usbi_dbg(DEVICE_CTX(dev), "can't get address");
 	} else {
 		dev->device_address = *addr;
 	}
@@ -530,7 +530,7 @@
 		dev->speed = LIBUSB_SPEED_SUPER;
 	}
 
-	usbi_dbg("vid=%x pid=%x, path=%s, bus_nmber=0x%x, port_number=%d, speed=%d",
+	usbi_dbg(DEVICE_CTX(dev), "vid=%x pid=%x, path=%s, bus_nmber=0x%x, port_number=%d, speed=%d",
 	    dev->device_descriptor.idVendor, dev->device_descriptor.idProduct,
 	    dpriv->phypath, dev->bus_number, dev->port_number, dev->speed);
 
@@ -571,7 +571,7 @@
 	dn = myself;
 	/* find the root hub */
 	while (di_prop_lookup_ints(DDI_DEV_T_ANY, dn, "root-hub", &j) != 0) {
-		usbi_dbg("find_root_hub:%s", di_devfs_path(dn));
+		usbi_dbg(NULL, "find_root_hub:%s", di_devfs_path(dn));
 		n = di_prop_lookup_ints(DDI_DEV_T_ANY, dn,
 				"assigned-address", &addr_prop);
 		session_id |= ((addr_prop[0] & 0xff) << i++ * 8);
@@ -586,13 +586,13 @@
 	session_id |= (bdf << i * 8);
 	bus_number = (PCI_REG_DEV_G(reg) << 3) | PCI_REG_FUNC_G(reg);
 
-	usbi_dbg("device bus address=%s:%x, name:%s",
+	usbi_dbg(NULL, "device bus address=%s:%x, name:%s",
 	    di_bus_addr(myself), bus_number, di_node_name(dn));
-	usbi_dbg("session id org:%" PRIx64, session_id);
+	usbi_dbg(NULL, "session id org:%" PRIx64, session_id);
 
 	/* dn is the usb device */
 	for (dn = di_child_node(myself); dn != DI_NODE_NIL; dn = di_sibling_node(dn)) {
-		usbi_dbg("device path:%s", di_devfs_path(dn));
+		usbi_dbg(NULL, "device path:%s", di_devfs_path(dn));
 		/* skip hub devices, because its driver can not been unload */
 		if (di_prop_lookup_ints(DDI_DEV_T_ANY, dn, "usb-port-count", &addr_prop) != -1)
 			continue;
@@ -600,18 +600,18 @@
 		n = di_prop_lookup_ints(DDI_DEV_T_ANY, dn,
 		    "assigned-address", &addr_prop);
 		if ((n != 1) || (addr_prop[0] == 0)) {
-			usbi_dbg("cannot get valid usb_addr");
+			usbi_dbg(NULL, "cannot get valid usb_addr");
 			continue;
 		}
 
 		sid = (session_id << 8) | (addr_prop[0] & 0xff) ;
-		usbi_dbg("session id %" PRIX64, sid);
+		usbi_dbg(NULL, "session id %" PRIX64, sid);
 
 		dev = usbi_get_device_by_session_id(nargs->ctx, sid);
 		if (dev == NULL) {
 			dev = usbi_alloc_device(nargs->ctx, sid);
 			if (dev == NULL) {
-				usbi_dbg("can't alloc device");
+				usbi_dbg(NULL, "can't alloc device");
 				continue;
 			}
 			devpriv = usbi_get_device_priv(dev);
@@ -619,21 +619,21 @@
 
 			if (sunos_fill_in_dev_info(dn, dev) != LIBUSB_SUCCESS) {
 				libusb_unref_device(dev);
-				usbi_dbg("get information fail");
+				usbi_dbg(NULL, "get information fail");
 				continue;
 			}
 			if (usbi_sanitize_device(dev) < 0) {
 				libusb_unref_device(dev);
-				usbi_dbg("sanatize failed: ");
+				usbi_dbg(NULL, "sanatize failed: ");
 				return (DI_WALK_TERMINATE);
 			}
 		} else {
 			devpriv = usbi_get_device_priv(dev);
-			usbi_dbg("Dev %s exists", devpriv->ugenpath);
+			usbi_dbg(NULL, "Dev %s exists", devpriv->ugenpath);
 		}
 
 		if (discovered_devs_append(*(nargs->discdevs), dev) == NULL) {
-			usbi_dbg("cannot append device");
+			usbi_dbg(NULL, "cannot append device");
 		}
 
 		/*
@@ -642,7 +642,7 @@
 		 */
 		libusb_unref_device(dev);
 
-		usbi_dbg("Device %s %s id=0x%" PRIx64 ", devcount:%" PRIuPTR
+		usbi_dbg(NULL, "Device %s %s id=0x%" PRIx64 ", devcount:%" PRIuPTR
 		    ", bdf=%" PRIx64,
 		    devpriv->ugenpath, di_devfs_path(dn), (uint64_t)sid,
 		    (*nargs->discdevs)->len, bdf);
@@ -690,13 +690,13 @@
 	args.discdevs = discdevs;
 	args.last_ugenpath = NULL;
 	if ((root_node = di_init("/", DINFOCPYALL)) == DI_NODE_NIL) {
-		usbi_dbg("di_int() failed: errno %d (%s)", errno, strerror(errno));
+		usbi_dbg(ctx, "di_int() failed: errno %d (%s)", errno, strerror(errno));
 		return (LIBUSB_ERROR_IO);
 	}
 
 	if ((devlink_hdl = di_devlink_init(NULL, 0)) == NULL) {
 		di_fini(root_node);
-		usbi_dbg("di_devlink_init() failed: errno %d (%s)", errno, strerror(errno));
+		usbi_dbg(ctx, "di_devlink_init() failed: errno %d (%s)", errno, strerror(errno));
 
 		return (LIBUSB_ERROR_IO);
 	}
@@ -705,7 +705,7 @@
 	/* walk each node to find USB devices */
 	if (di_walk_node(root_node, DI_WALK_SIBFIRST, &args,
 	    sunos_walk_minor_node_link) == -1) {
-		usbi_dbg("di_walk_node() failed: errno %d (%s)", errno, strerror(errno));
+		usbi_dbg(ctx, "di_walk_node() failed: errno %d (%s)", errno, strerror(errno));
 		di_fini(root_node);
 
 		return (LIBUSB_ERROR_IO);
@@ -714,7 +714,7 @@
 	di_fini(root_node);
 	di_devlink_fini(&devlink_hdl);
 
-	usbi_dbg("%zu devices", (*discdevs)->len);
+	usbi_dbg(ctx, "%zu devices", (*discdevs)->len);
 
 	return ((*discdevs)->len);
 }
@@ -729,7 +729,7 @@
 	}
 	snprintf(filename, PATH_MAX, "%s/cntrl0", dpriv->ugenpath);
 
-	usbi_dbg("opening %s", filename);
+	usbi_dbg(NULL, "opening %s", filename);
 	hpriv->eps[0].datafd = open(filename, O_RDWR);
 	if (hpriv->eps[0].datafd < 0) {
 		return(_errno_to_libusb(errno));
@@ -836,20 +836,20 @@
 	uint8_t	ep_index;
 	sunos_dev_handle_priv_t *hpriv;
 
-	usbi_dbg("open ep 0x%02x", ep_addr);
+	usbi_dbg(HANDLE_CTX(hdl), "open ep 0x%02x", ep_addr);
 	hpriv = usbi_get_device_handle_priv(hdl);
 	ep_index = sunos_usb_ep_index(ep_addr);
 	/* ep already opened */
 	if ((hpriv->eps[ep_index].datafd > 0) &&
 	    (hpriv->eps[ep_index].statfd > 0)) {
-		usbi_dbg("ep 0x%02x already opened, return success",
+		usbi_dbg(HANDLE_CTX(hdl), "ep 0x%02x already opened, return success",
 			ep_addr);
 
 		return (0);
 	}
 
 	if (sunos_find_interface(hdl, ep_addr, &ifc) < 0) {
-		usbi_dbg("can't find interface for endpoint 0x%02x",
+		usbi_dbg(HANDLE_CTX(hdl), "can't find interface for endpoint 0x%02x",
 		    ep_addr);
 
 		return (EACCES);
@@ -896,7 +896,7 @@
 	}
 	/* Open the xfer endpoint first */
 	if ((fd = open(filename, mode)) == -1) {
-		usbi_dbg("can't open %s: errno %d (%s)", filename, errno,
+		usbi_dbg(HANDLE_CTX(hdl), "can't open %s: errno %d (%s)", filename, errno,
 		    strerror(errno));
 
 		return (errno);
@@ -917,7 +917,7 @@
 
 		/* Open the status endpoint with RDWR */
 		if ((fdstat = open(statfilename, O_RDWR)) == -1) {
-			usbi_dbg("can't open %s RDWR: errno %d (%s)",
+			usbi_dbg(HANDLE_CTX(hdl), "can't open %s RDWR: errno %d (%s)",
 				statfilename, errno, strerror(errno));
 
 			return (errno);
@@ -925,7 +925,7 @@
 			count = write(fdstat, &control, sizeof(control));
 			if (count != 1) {
 				/* this should have worked */
-				usbi_dbg("can't write to %s: errno %d (%s)",
+				usbi_dbg(HANDLE_CTX(hdl), "can't write to %s: errno %d (%s)",
 					statfilename, errno, strerror(errno));
 				(void) close(fdstat);
 
@@ -934,7 +934,7 @@
 		}
 	} else {
 		if ((fdstat = open(statfilename, O_RDONLY)) == -1) {
-			usbi_dbg("can't open %s: errno %d (%s)", statfilename, errno,
+			usbi_dbg(HANDLE_CTX(hdl), "can't open %s: errno %d (%s)", statfilename, errno,
 				strerror(errno));
 
 			return (errno);
@@ -943,7 +943,7 @@
 
 	/* Re-open the xfer endpoint */
 	if ((fd = open(filename, mode)) == -1) {
-		usbi_dbg("can't open %s: errno %d (%s)", filename, errno,
+		usbi_dbg(HANDLE_CTX(hdl), "can't open %s: errno %d (%s)", filename, errno,
 			strerror(errno));
 		(void) close(fdstat);
 
@@ -952,7 +952,7 @@
 
 	hpriv->eps[ep_index].datafd = fd;
 	hpriv->eps[ep_index].statfd = fdstat;
-	usbi_dbg("ep=0x%02x datafd=%d, statfd=%d", ep_addr, fd, fdstat);
+	usbi_dbg(HANDLE_CTX(hdl), "ep=0x%02x datafd=%d, statfd=%d", ep_addr, fd, fdstat);
 
 	return (0);
 }
@@ -981,7 +981,7 @@
 	}
 
 	if ((ret = sunos_usb_open_ep0(hpriv, dpriv)) != LIBUSB_SUCCESS) {
-		usbi_dbg("fail: %d", ret);
+		usbi_dbg(HANDLE_CTX(handle), "fail: %d", ret);
 		return (ret);
 	}
 
@@ -993,7 +993,7 @@
 {
 	sunos_dev_handle_priv_t *hpriv;
 
-	usbi_dbg(" ");
+	usbi_dbg(HANDLE_CTX(handle), " ");
 
 	hpriv = usbi_get_device_handle_priv(handle);
 
@@ -1016,14 +1016,14 @@
 	 * has ever been changed through setCfg.
 	 */
 	if ((node = di_init(dpriv->phypath, DINFOCPYALL)) == DI_NODE_NIL) {
-		usbi_dbg("di_int() failed: errno %d (%s)", errno,
+		usbi_dbg(DEVICE_CTX(dev), "di_int() failed: errno %d (%s)", errno,
 			strerror(errno));
 		return (LIBUSB_ERROR_IO);
 	}
 	proplen = di_prop_lookup_bytes(DDI_DEV_T_ANY, node,
 	    "usb-raw-cfg-descriptors", &rdata);
 	if (proplen <= 0) {
-		usbi_dbg("can't find raw config descriptors");
+		usbi_dbg(DEVICE_CTX(dev), "can't find raw config descriptors");
 
 		return (LIBUSB_ERROR_IO);
 	}
@@ -1040,7 +1040,7 @@
 	cfg = (struct libusb_config_descriptor *)dpriv->raw_cfgdescr;
 	len = MIN(len, libusb_le16_to_cpu(cfg->wTotalLength));
 	memcpy(buf, dpriv->raw_cfgdescr, len);
-	usbi_dbg("path:%s len %zu", dpriv->phypath, len);
+	usbi_dbg(DEVICE_CTX(dev), "path:%s len %zu", dpriv->phypath, len);
 
 	return (len);
 }
@@ -1061,7 +1061,7 @@
 
 	*config = dpriv->cfgvalue;
 
-	usbi_dbg("bConfigurationValue %u", *config);
+	usbi_dbg(HANDLE_CTX(handle), "bConfigurationValue %u", *config);
 
 	return (LIBUSB_SUCCESS);
 }
@@ -1072,7 +1072,7 @@
 	sunos_dev_priv_t *dpriv = usbi_get_device_priv(handle->dev);
 	sunos_dev_handle_priv_t *hpriv;
 
-	usbi_dbg("bConfigurationValue %d", config);
+	usbi_dbg(HANDLE_CTX(handle), "bConfigurationValue %d", config);
 	hpriv = usbi_get_device_handle_priv(handle);
 
 	if (dpriv->ugenpath == NULL)
@@ -1092,7 +1092,7 @@
 {
 	UNUSED(handle);
 
-	usbi_dbg("iface %u", iface);
+	usbi_dbg(HANDLE_CTX(handle), "iface %u", iface);
 
 	return (LIBUSB_SUCCESS);
 }
@@ -1102,7 +1102,7 @@
 {
 	sunos_dev_handle_priv_t *hpriv = usbi_get_device_handle_priv(handle);
 
-	usbi_dbg("iface %u", iface);
+	usbi_dbg(HANDLE_CTX(handle), "iface %u", iface);
 
 	/* XXX: can we release it? */
 	hpriv->altsetting[iface] = 0;
@@ -1117,7 +1117,7 @@
 	sunos_dev_priv_t *dpriv = usbi_get_device_priv(handle->dev);
 	sunos_dev_handle_priv_t *hpriv = usbi_get_device_handle_priv(handle);
 
-	usbi_dbg("iface %u, setting %u", iface, altsetting);
+	usbi_dbg(HANDLE_CTX(handle), "iface %u, setting %u", iface, altsetting);
 
 	if (dpriv->ugenpath == NULL)
 		return (LIBUSB_ERROR_NOT_FOUND);
@@ -1169,7 +1169,7 @@
 
 		ret = aio_error(aiocb);
 		if (ret != 0) {
-			xfer->status = sunos_usb_get_status(hpriv->eps[ep].statfd);
+			xfer->status = sunos_usb_get_status(TRANSFER_CTX(xfer), hpriv->eps[ep].statfd);
 		} else {
 			xfer->actual_length =
 			    LIBUSB_TRANSFER_TO_USBI_TRANSFER(xfer)->transferred =
@@ -1178,7 +1178,7 @@
 
 		usb_dump_data(xfer->buffer, xfer->actual_length);
 
-		usbi_dbg("ret=%d, len=%d, actual_len=%d", ret, xfer->length,
+		usbi_dbg(TRANSFER_CTX(xfer), "ret=%d, len=%d, actual_len=%d", ret, xfer->length,
 		    xfer->actual_length);
 
 		/* async notification */
@@ -1195,7 +1195,7 @@
 	uint8_t ep;
 	struct sunos_transfer_priv *tpriv;
 
-	usbi_dbg(" ");
+	usbi_dbg(TRANSFER_CTX(transfer), " ");
 
 	tpriv = usbi_get_transfer_priv(LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer));
 	hpriv = usbi_get_device_handle_priv(transfer->dev_handle);
@@ -1225,12 +1225,12 @@
 
 /* return the number of bytes read/written */
 static ssize_t
-usb_do_io(int fd, int stat_fd, void *data, size_t size, int flag, int *status)
+usb_do_io(struct libusb_context *ctx, int fd, int stat_fd, void *data, size_t size, int flag, int *status)
 {
 	int error;
 	ssize_t ret = -1;
 
-	usbi_dbg("usb_do_io(): datafd=%d statfd=%d size=0x%zx flag=%s",
+	usbi_dbg(ctx, "usb_do_io(): datafd=%d statfd=%d size=0x%zx flag=%s",
 	    fd, stat_fd, size, flag? "WRITE":"READ");
 
 	switch (flag) {
@@ -1246,17 +1246,17 @@
 		break;
 	}
 
-	usbi_dbg("usb_do_io(): amount=%zd", ret);
+	usbi_dbg(ctx, "usb_do_io(): amount=%zd", ret);
 
 	if (ret < 0) {
 		int save_errno = errno;
 
-		usbi_dbg("TID=%x io %s errno %d (%s)", pthread_self(),
+		usbi_dbg(ctx, "TID=%x io %s errno %d (%s)", pthread_self(),
 		    flag?"WRITE":"READ", errno, strerror(errno));
 
 		/* sunos_usb_get_status will do a read and overwrite errno */
-		error = sunos_usb_get_status(stat_fd);
-		usbi_dbg("io status=%d errno %d (%s)", error,
+		error = sunos_usb_get_status(ctx, stat_fd);
+		usbi_dbg(ctx, "io status=%d errno %d (%s)", error,
 			save_errno, strerror(save_errno));
 
 		if (status) {
@@ -1286,26 +1286,26 @@
 	wLength = transfer->length - LIBUSB_CONTROL_SETUP_SIZE;
 
 	if (hpriv->eps[0].datafd == -1) {
-		usbi_dbg("ep0 not opened");
+		usbi_dbg(TRANSFER_CTX(transfer), "ep0 not opened");
 
 		return (LIBUSB_ERROR_NOT_FOUND);
 	}
 
 	if ((data[0] & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) {
-		usbi_dbg("IN request");
-		ret = usb_do_io(hpriv->eps[0].datafd,
+		usbi_dbg(TRANSFER_CTX(transfer), "IN request");
+		ret = usb_do_io(TRANSFER_CTX(transfer), hpriv->eps[0].datafd,
 		    hpriv->eps[0].statfd, data, LIBUSB_CONTROL_SETUP_SIZE,
 		    WRITE, &status);
 	} else {
-		usbi_dbg("OUT request");
-		ret = usb_do_io(hpriv->eps[0].datafd, hpriv->eps[0].statfd,
+		usbi_dbg(TRANSFER_CTX(transfer), "OUT request");
+		ret = usb_do_io(TRANSFER_CTX(transfer), hpriv->eps[0].datafd, hpriv->eps[0].statfd,
 		    transfer->buffer, transfer->length, WRITE,
 		    (int *)&transfer->status);
 	}
 
 	setup_ret = ret;
 	if (ret < (ssize_t)LIBUSB_CONTROL_SETUP_SIZE) {
-		usbi_dbg("error sending control msg: %zd", ret);
+		usbi_dbg(TRANSFER_CTX(transfer), "error sending control msg: %zd", ret);
 
 		return (LIBUSB_ERROR_IO);
 	}
@@ -1315,8 +1315,8 @@
 	/* Read the remaining bytes for IN request */
 	if ((wLength) && ((data[0] & LIBUSB_ENDPOINT_DIR_MASK) ==
 	    LIBUSB_ENDPOINT_IN)) {
-		usbi_dbg("DATA: %d", transfer->length - (int)setup_ret);
-		ret = usb_do_io(hpriv->eps[0].datafd,
+		usbi_dbg(TRANSFER_CTX(transfer), "DATA: %d", transfer->length - (int)setup_ret);
+		ret = usb_do_io(TRANSFER_CTX(transfer), hpriv->eps[0].datafd,
 			hpriv->eps[0].statfd,
 			transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE,
 			wLength, READ, (int *)&transfer->status);
@@ -1325,7 +1325,7 @@
 	if (ret >= 0) {
 		LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer)->transferred = ret;
 	}
-	usbi_dbg("Done: ctrl data bytes %zd", ret);
+	usbi_dbg(TRANSFER_CTX(transfer), "Done: ctrl data bytes %zd", ret);
 
 	/**
 	 * Sync transfer handling.
@@ -1345,13 +1345,13 @@
 {
 	int ret;
 
-	usbi_dbg("endpoint=0x%02x", endpoint);
+	usbi_dbg(HANDLE_CTX(handle), "endpoint=0x%02x", endpoint);
 
 	ret = libusb_control_transfer(handle, LIBUSB_ENDPOINT_OUT |
 	    LIBUSB_RECIPIENT_ENDPOINT | LIBUSB_REQUEST_TYPE_STANDARD,
 	    LIBUSB_REQUEST_CLEAR_FEATURE, 0, endpoint, NULL, 0, 1000);
 
-	usbi_dbg("ret=%d", ret);
+	usbi_dbg(HANDLE_CTX(handle), "ret=%d", ret);
 
 	return (ret);
 }
@@ -1361,7 +1361,7 @@
 {
 	sunos_dev_priv_t *dpriv = usbi_get_device_priv(dev);
 
-	usbi_dbg("destroy everything");
+	usbi_dbg(DEVICE_CTX(dev), "destroy everything");
 	free(dpriv->raw_cfgdescr);
 	free(dpriv->ugenpath);
 	free(dpriv->phypath);
@@ -1387,7 +1387,7 @@
 	switch (transfer->type) {
 	case LIBUSB_TRANSFER_TYPE_CONTROL:
 		/* sync transfer */
-		usbi_dbg("CTRL transfer: %d", transfer->length);
+		usbi_dbg(ITRANSFER_CTX(itransfer), "CTRL transfer: %d", transfer->length);
 		err = solaris_submit_ctrl_on_default(transfer);
 		break;
 
@@ -1395,9 +1395,9 @@
 		/* fallthru */
 	case LIBUSB_TRANSFER_TYPE_INTERRUPT:
 		if (transfer->type == LIBUSB_TRANSFER_TYPE_BULK)
-			usbi_dbg("BULK transfer: %d", transfer->length);
+			usbi_dbg(ITRANSFER_CTX(itransfer), "BULK transfer: %d", transfer->length);
 		else
-			usbi_dbg("INTR transfer: %d", transfer->length);
+			usbi_dbg(ITRANSFER_CTX(itransfer), "INTR transfer: %d", transfer->length);
 		err = sunos_do_async_io(transfer);
 		break;
 
@@ -1407,9 +1407,9 @@
 		/* fallthru */
 	case LIBUSB_TRANSFER_TYPE_BULK_STREAM:
 		if (transfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS)
-			usbi_dbg("ISOC transfer: %d", transfer->length);
+			usbi_dbg(ITRANSFER_CTX(itransfer), "ISOC transfer: %d", transfer->length);
 		else
-			usbi_dbg("BULK STREAM transfer: %d", transfer->length);
+			usbi_dbg(ITRANSFER_CTX(itransfer), "BULK STREAM transfer: %d", transfer->length);
 		err = LIBUSB_ERROR_NOT_SUPPORTED;
 		break;
 	}
@@ -1435,7 +1435,7 @@
 
 	ret = aio_cancel(hpriv->eps[ep].datafd, aiocb);
 
-	usbi_dbg("aio->fd=%d fd=%d ret = %d, %s", aiocb->aio_fildes,
+	usbi_dbg(ITRANSFER_CTX(itransfer), "aio->fd=%d fd=%d ret = %d, %s", aiocb->aio_fildes,
 	    hpriv->eps[ep].datafd, ret, (ret == AIO_CANCELED)?
 	    strerror(0):strerror(errno));
 
@@ -1461,7 +1461,7 @@
 int
 _errno_to_libusb(int err)
 {
-	usbi_dbg("error: %s (%d)", strerror(err), err);
+	usbi_dbg(NULL, "error: %s (%d)", strerror(err), err);
 
 	switch (err) {
 	case EIO:
@@ -1486,96 +1486,96 @@
  * Returns: ugen's last cmd status
  */
 static int
-sunos_usb_get_status(int fd)
+sunos_usb_get_status(struct libusb_context *ctx, int fd)
 {
 	int status;
 	ssize_t ret;
 
-	usbi_dbg("sunos_usb_get_status(): fd=%d", fd);
+	usbi_dbg(ctx, "sunos_usb_get_status(): fd=%d", fd);
 
 	ret = read(fd, &status, sizeof(status));
 	if (ret == sizeof(status)) {
 		switch (status) {
 		case USB_LC_STAT_NOERROR:
-			usbi_dbg("No Error");
+			usbi_dbg(ctx, "No Error");
 			break;
 		case USB_LC_STAT_CRC:
-			usbi_dbg("CRC Timeout Detected\n");
+			usbi_dbg(ctx, "CRC Timeout Detected\n");
 			break;
 		case USB_LC_STAT_BITSTUFFING:
-			usbi_dbg("Bit Stuffing Violation\n");
+			usbi_dbg(ctx, "Bit Stuffing Violation\n");
 			break;
 		case USB_LC_STAT_DATA_TOGGLE_MM:
-			usbi_dbg("Data Toggle Mismatch\n");
+			usbi_dbg(ctx, "Data Toggle Mismatch\n");
 			break;
 		case USB_LC_STAT_STALL:
-			usbi_dbg("End Point Stalled\n");
+			usbi_dbg(ctx, "End Point Stalled\n");
 			break;
 		case USB_LC_STAT_DEV_NOT_RESP:
-			usbi_dbg("Device is Not Responding\n");
+			usbi_dbg(ctx, "Device is Not Responding\n");
 			break;
 		case USB_LC_STAT_PID_CHECKFAILURE:
-			usbi_dbg("PID Check Failure\n");
+			usbi_dbg(ctx, "PID Check Failure\n");
 			break;
 		case USB_LC_STAT_UNEXP_PID:
-			usbi_dbg("Unexpected PID\n");
+			usbi_dbg(ctx, "Unexpected PID\n");
 			break;
 		case USB_LC_STAT_DATA_OVERRUN:
-			usbi_dbg("Data Exceeded Size\n");
+			usbi_dbg(ctx, "Data Exceeded Size\n");
 			break;
 		case USB_LC_STAT_DATA_UNDERRUN:
-			usbi_dbg("Less data received\n");
+			usbi_dbg(ctx, "Less data received\n");
 			break;
 		case USB_LC_STAT_BUFFER_OVERRUN:
-			usbi_dbg("Buffer Size Exceeded\n");
+			usbi_dbg(ctx, "Buffer Size Exceeded\n");
 			break;
 		case USB_LC_STAT_BUFFER_UNDERRUN:
-			usbi_dbg("Buffer Underrun\n");
+			usbi_dbg(ctx, "Buffer Underrun\n");
 			break;
 		case USB_LC_STAT_TIMEOUT:
-			usbi_dbg("Command Timed Out\n");
+			usbi_dbg(ctx, "Command Timed Out\n");
 			break;
 		case USB_LC_STAT_NOT_ACCESSED:
-			usbi_dbg("Not Accessed by h/w\n");
+			usbi_dbg(ctx, "Not Accessed by h/w\n");
 			break;
 		case USB_LC_STAT_UNSPECIFIED_ERR:
-			usbi_dbg("Unspecified Error\n");
+			usbi_dbg(ctx, "Unspecified Error\n");
 			break;
 		case USB_LC_STAT_NO_BANDWIDTH:
-			usbi_dbg("No Bandwidth\n");
+			usbi_dbg(ctx, "No Bandwidth\n");
 			break;
 		case USB_LC_STAT_HW_ERR:
-			usbi_dbg("Host Controller h/w Error\n");
+			usbi_dbg(ctx, "Host Controller h/w Error\n");
 			break;
 		case USB_LC_STAT_SUSPENDED:
-			usbi_dbg("Device was Suspended\n");
+			usbi_dbg(ctx, "Device was Suspended\n");
 			break;
 		case USB_LC_STAT_DISCONNECTED:
-			usbi_dbg("Device was Disconnected\n");
+			usbi_dbg(ctx, "Device was Disconnected\n");
 			break;
 		case USB_LC_STAT_INTR_BUF_FULL:
-			usbi_dbg("Interrupt buffer was full\n");
+			usbi_dbg(ctx, "Interrupt buffer was full\n");
 			break;
 		case USB_LC_STAT_INVALID_REQ:
-			usbi_dbg("Request was Invalid\n");
+			usbi_dbg(ctx, "Request was Invalid\n");
 			break;
 		case USB_LC_STAT_INTERRUPTED:
-			usbi_dbg("Request was Interrupted\n");
+			usbi_dbg(ctx, "Request was Interrupted\n");
 			break;
 		case USB_LC_STAT_NO_RESOURCES:
-			usbi_dbg("No resources available for "
+			usbi_dbg(ctx, "No resources available for "
 			    "request\n");
 			break;
 		case USB_LC_STAT_INTR_POLLING_FAILED:
-			usbi_dbg("Failed to Restart Poll");
+			usbi_dbg(ctx, "Failed to Restart Poll");
 			break;
 		default:
-			usbi_dbg("Error Not Determined %d\n",
+			usbi_dbg(ctx, "Error Not Determined %d\n",
 			    status);
 			break;
 		}
 	} else {
-		usbi_dbg("read stat error: %s",strerror(errno));
+		usbi_dbg(ctx, "read stat error: %s",strerror(errno));
 		status = -1;
 	}
 
diff --git a/libusb/os/windows_common.c b/libusb/os/windows_common.c
index e7484ff..eefd01e 100644
--- a/libusb/os/windows_common.c
+++ b/libusb/os/windows_common.c
@@ -152,7 +152,7 @@
 	// Create a mutex
 	usbi_mutex_init(&htab_mutex);
 
-	usbi_dbg("using %lu entries hash table", HTAB_SIZE);
+	usbi_dbg(ctx, "using %lu entries hash table", HTAB_SIZE);
 	htab_filled = 0;
 
 	// allocate memory and zero out.
@@ -221,7 +221,7 @@
 		if ((htab_table[idx].used == hval) && (strcmp(str, htab_table[idx].str) == 0))
 			goto out_unlock; // existing hash
 
-		usbi_dbg("hash collision ('%s' vs '%s')", str, htab_table[idx].str);
+		usbi_dbg(NULL, "hash collision ('%s' vs '%s')", str, htab_table[idx].str);
 
 		// Second hash function, as suggested in [Knuth]
 		hval2 = 1UL + hval % (HTAB_SIZE - 2);
@@ -283,7 +283,7 @@
 	case USBD_STATUS_DEVICE_GONE:
 		return LIBUSB_TRANSFER_NO_DEVICE;
 	default:
-		usbi_dbg("USBD_STATUS 0x%08lx translated to LIBUSB_TRANSFER_ERROR", ULONG_CAST(status));
+		usbi_dbg(NULL, "USBD_STATUS 0x%08lx translated to LIBUSB_TRANSFER_ERROR", ULONG_CAST(status));
 		return LIBUSB_TRANSFER_ERROR;
 	}
 }
@@ -298,7 +298,7 @@
 	struct windows_transfer_priv *transfer_priv = usbi_get_transfer_priv(itransfer);
 	OVERLAPPED *overlapped = &transfer_priv->overlapped;
 
-	usbi_dbg("transfer %p, length %lu", transfer, ULONG_CAST(size));
+	usbi_dbg(TRANSFER_CTX(transfer), "transfer %p, length %lu", transfer, ULONG_CAST(size));
 
 	overlapped->Internal = (ULONG_PTR)STATUS_SUCCESS;
 	overlapped->InternalHigh = (ULONG_PTR)size;
@@ -401,11 +401,11 @@
 	arch = is_x64() ? "64-bit" : "32-bit";
 
 	if (vi.wServicePackMinor)
-		usbi_dbg("Windows %s SP%u.%u %s", w, vi.wServicePackMajor, vi.wServicePackMinor, arch);
+		usbi_dbg(NULL, "Windows %s SP%u.%u %s", w, vi.wServicePackMajor, vi.wServicePackMinor, arch);
 	else if (vi.wServicePackMajor)
-		usbi_dbg("Windows %s SP%u %s", w, vi.wServicePackMajor, arch);
+		usbi_dbg(NULL, "Windows %s SP%u %s", w, vi.wServicePackMajor, arch);
 	else
-		usbi_dbg("Windows %s %s", w, arch);
+		usbi_dbg(NULL, "Windows %s %s", w, arch);
 
 	return winver;
 }
@@ -425,7 +425,7 @@
 	struct usbi_transfer *itransfer;
 	bool found;
 
-	usbi_dbg("I/O completion thread started");
+	usbi_dbg(ctx, "I/O completion thread started");
 
 	while (true) {
 		overlapped = NULL;
@@ -471,18 +471,18 @@
 		usbi_mutex_unlock(&ctx->open_devs_lock);
 
 		if (!found) {
-			usbi_dbg("ignoring overlapped %p for handle %p (device %u.%u)",
+			usbi_dbg(ctx, "ignoring overlapped %p for handle %p (device %u.%u)",
 				overlapped, dev_handle, dev_handle->dev->bus_number, dev_handle->dev->device_address);
 			continue;
 		}
 
 		itransfer = (struct usbi_transfer *)((unsigned char *)transfer_priv + PTR_ALIGN(sizeof(*transfer_priv)));
-		usbi_dbg("transfer %p completed, length %lu",
+		usbi_dbg(ctx, "transfer %p completed, length %lu",
 			 USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer), ULONG_CAST(num_bytes));
 		usbi_signal_transfer_completion(itransfer);
 	}
 
-	usbi_dbg("I/O completion thread exiting");
+	usbi_dbg(ctx, "I/O completion thread exiting");
 
 	return 0;
 }
@@ -519,7 +519,7 @@
 
 		r = usbdk_backend.init(ctx);
 		if (r == LIBUSB_SUCCESS) {
-			usbi_dbg("UsbDk backend is available");
+			usbi_dbg(ctx, "UsbDk backend is available");
 			usbdk_available = true;
 		} else {
 			usbi_info(ctx, "UsbDk backend is not available");
@@ -600,7 +600,7 @@
 			usbi_err(ctx, "UsbDk backend not available");
 			return LIBUSB_ERROR_NOT_FOUND;
 		}
-		usbi_dbg("switching context %p to use UsbDk backend", ctx);
+		usbi_dbg(ctx, "switching context %p to use UsbDk backend", ctx);
 		priv->backend = &usbdk_backend;
 		return LIBUSB_SUCCESS;
 	}
@@ -790,7 +790,7 @@
 	else
 		result = GetLastError();
 
-	usbi_dbg("handling transfer %p completion with errcode %lu, length %lu",
+	usbi_dbg(ctx, "handling transfer %p completion with errcode %lu, length %lu",
 		 USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer), ULONG_CAST(result), ULONG_CAST(bytes_transferred));
 
 	switch (result) {
@@ -798,25 +798,25 @@
 		status = backend->copy_transfer_data(itransfer, bytes_transferred);
 		break;
 	case ERROR_GEN_FAILURE:
-		usbi_dbg("detected endpoint stall");
+		usbi_dbg(ctx, "detected endpoint stall");
 		status = LIBUSB_TRANSFER_STALL;
 		break;
 	case ERROR_SEM_TIMEOUT:
-		usbi_dbg("detected semaphore timeout");
+		usbi_dbg(ctx, "detected semaphore timeout");
 		status = LIBUSB_TRANSFER_TIMED_OUT;
 		break;
 	case ERROR_OPERATION_ABORTED:
 		istatus = backend->copy_transfer_data(itransfer, bytes_transferred);
 		if (istatus != LIBUSB_TRANSFER_COMPLETED)
-			usbi_dbg("failed to copy partial data in aborted operation: %d", (int)istatus);
+			usbi_dbg(ctx, "failed to copy partial data in aborted operation: %d", (int)istatus);
 
-		usbi_dbg("detected operation aborted");
+		usbi_dbg(ctx, "detected operation aborted");
 		status = LIBUSB_TRANSFER_CANCELLED;
 		break;
 	case ERROR_FILE_NOT_FOUND:
 	case ERROR_DEVICE_NOT_CONNECTED:
 	case ERROR_NO_SUCH_DEVICE:
-		usbi_dbg("detected device removed");
+		usbi_dbg(ctx, "detected device removed");
 		status = LIBUSB_TRANSFER_NO_DEVICE;
 		break;
 	default:
diff --git a/libusb/os/windows_winusb.c b/libusb/os/windows_winusb.c
index 4ddd3dc..299de16 100644
--- a/libusb/os/windows_winusb.c
+++ b/libusb/os/windows_winusb.c
@@ -416,7 +416,7 @@
 				// libusb0.sys is connected to this device instance.
 				// If the the device interface guid is {F9F3FF14-AE21-48A0-8A25-8011A7A931D9} then it's a filter.
 				sprintf(filter_path, "\\\\.\\libusb0-%04u", (unsigned int)libusb0_symboliclink_index);
-				usbi_dbg("assigned libusb0 symbolic link %s", filter_path);
+				usbi_dbg(ctx, "assigned libusb0 symbolic link %s", filter_path);
 			} else {
 				// libusb0.sys was connected to this device instance at one time; but not anymore.
 			}
@@ -474,14 +474,14 @@
 			intf_desc = &intf->altsetting[j];
 			for (k = 0; k < intf_desc->bNumEndpoints; k++) {
 				if (intf_desc->endpoint[k].bEndpointAddress == ep) {
-					usbi_dbg("found endpoint %02X on interface %d", intf_desc->bInterfaceNumber, i);
+					usbi_dbg(NULL, "found endpoint %02X on interface %d", intf_desc->bInterfaceNumber, i);
 					return intf_desc->bInterfaceNumber;
 				}
 			}
 		}
 	}
 
-	usbi_dbg("endpoint %02X not found on any interface", ep);
+	usbi_dbg(NULL, "endpoint %02X not found on any interface", ep);
 	return LIBUSB_ERROR_NOT_FOUND;
 }
 
@@ -527,7 +527,7 @@
 	safe_free(priv->usb_interface[iface].endpoint);
 
 	if (if_desc->bNumEndpoints == 0) {
-		usbi_dbg("no endpoints found for interface %u", iface);
+		usbi_dbg(HANDLE_CTX(dev_handle), "no endpoints found for interface %u", iface);
 		libusb_free_config_descriptor(conf_desc);
 		priv->usb_interface[iface].current_altsetting = altsetting;
 		return LIBUSB_SUCCESS;
@@ -542,7 +542,7 @@
 	priv->usb_interface[iface].nb_endpoints = if_desc->bNumEndpoints;
 	for (i = 0; i < if_desc->bNumEndpoints; i++) {
 		priv->usb_interface[iface].endpoint[i] = if_desc->endpoint[i].bEndpointAddress;
-		usbi_dbg("(re)assigned endpoint %02X to interface %u", priv->usb_interface[iface].endpoint[i], iface);
+		usbi_dbg(HANDLE_CTX(dev_handle), "(re)assigned endpoint %02X to interface %u", priv->usb_interface[iface].endpoint[i], iface);
 	}
 	libusb_free_config_descriptor(conf_desc);
 
@@ -612,7 +612,7 @@
 			// Must claim an interface of the same API type
 			if ((priv->usb_interface[current_interface].apib->id == api_type)
 					&& (libusb_claim_interface(transfer->dev_handle, current_interface) == LIBUSB_SUCCESS)) {
-				usbi_dbg("auto-claimed interface %d for control request", current_interface);
+				usbi_dbg(TRANSFER_CTX(transfer), "auto-claimed interface %d for control request", current_interface);
 				if (handle_priv->autoclaim_count[current_interface] != 0)
 					usbi_err(TRANSFER_CTX(transfer), "program assertion failed - autoclaim_count was nonzero");
 				handle_priv->autoclaim_count[current_interface]++;
@@ -649,9 +649,9 @@
 		if (handle_priv->autoclaim_count[transfer_priv->interface_number] == 0) {
 			r = libusb_release_interface(dev_handle, transfer_priv->interface_number);
 			if (r == LIBUSB_SUCCESS)
-				usbi_dbg("auto-released interface %d", transfer_priv->interface_number);
+				usbi_dbg(ITRANSFER_CTX(itransfer), "auto-released interface %d", transfer_priv->interface_number);
 			else
-				usbi_dbg("failed to auto-release interface %d (%s)",
+				usbi_dbg(ITRANSFER_CTX(itransfer), "failed to auto-release interface %d (%s)",
 					transfer_priv->interface_number, libusb_error_name((enum libusb_error)r));
 		}
 	}
@@ -792,7 +792,7 @@
 			continue;
 		}
 
-		usbi_dbg("cached config descriptor %u (bConfigurationValue=%u, %u bytes)",
+		usbi_dbg(ctx, "cached config descriptor %u (bConfigurationValue=%u, %u bytes)",
 			i, cd_data->bConfigurationValue, cd_data->wTotalLength);
 
 		// Cache the descriptor
@@ -909,7 +909,7 @@
 	}
 
 	num_ports = hub_info.u.HubInformation.HubDescriptor.bNumberOfPorts;
-	usbi_dbg("root hub '%s' reports %lu ports", priv->dev_id, ULONG_CAST(num_ports));
+	usbi_dbg(ctx, "root hub '%s' reports %lu ports", priv->dev_id, ULONG_CAST(num_ports));
 
 	if (windows_version >= WINDOWS_8) {
 		// Windows 8 and later is better at reporting the speed capabilities of the root hub,
@@ -1044,7 +1044,7 @@
 static int init_device(struct libusb_device *dev, struct libusb_device *parent_dev,
 	uint8_t port_number, DEVINST devinst)
 {
-	struct libusb_context *ctx;
+	struct libusb_context *ctx = NULL;
 	struct libusb_device *tmp_dev;
 	struct winusb_device_priv *priv, *parent_priv, *tmp_priv;
 	USB_NODE_CONNECTION_INFORMATION_EX conn_info;
@@ -1143,7 +1143,7 @@
 
 			priv->active_config = conn_info.CurrentConfigurationValue;
 			if (priv->active_config == 0) {
-				usbi_dbg("0x%x:0x%x found %u configurations (not configured)",
+				usbi_dbg(ctx, "0x%x:0x%x found %u configurations (not configured)",
 					dev->device_descriptor.idVendor,
 					dev->device_descriptor.idProduct,
 					dev->device_descriptor.bNumConfigurations);
@@ -1166,7 +1166,7 @@
 				dev->device_descriptor.bNumConfigurations);
 			priv->active_config = 1;
 		} else {
-			usbi_dbg("found %u configurations (current config: %u)", dev->device_descriptor.bNumConfigurations, priv->active_config);
+			usbi_dbg(ctx, "found %u configurations (current config: %u)", dev->device_descriptor.bNumConfigurations, priv->active_config);
 		}
 
 		// Cache as many config descriptors as we can
@@ -1217,7 +1217,7 @@
 
 	priv->initialized = true;
 
-	usbi_dbg("(bus: %u, addr: %u, depth: %u, port: %u): '%s'",
+	usbi_dbg(ctx, "(bus: %u, addr: %u, depth: %u, port: %u): '%s'",
 		dev->bus_number, dev->device_address, priv->depth, dev->port_number, priv->dev_id);
 
 	return LIBUSB_SUCCESS;
@@ -1286,7 +1286,7 @@
 
 	if (dev->bus_number == 0) {
 		// Only do this once
-		usbi_dbg("assigning HCD '%s' bus number %u", dev_id, bus_number);
+		usbi_dbg(ctx, "assigning HCD '%s' bus number %u", dev_id, bus_number);
 		dev->bus_number = bus_number;
 
 		if (sscanf(dev_id, "PCI\\VEN_%04hx&DEV_%04hx%*s", &dev->device_descriptor.idVendor, &dev->device_descriptor.idProduct) != 2)
@@ -1330,10 +1330,10 @@
 				if (lookup[k].list[l] == 0)
 					lookup[k].list[l] = LIST_SEPARATOR;
 			}
-			usbi_dbg("%s(s): %s", lookup[k].designation, lookup[k].list);
+			usbi_dbg(NULL, "%s(s): %s", lookup[k].designation, lookup[k].list);
 		} else {
 			if (GetLastError() != ERROR_INVALID_DATA)
-				usbi_dbg("could not access %s: %s", lookup[k].designation, windows_error_str(0));
+				usbi_dbg(NULL, "could not access %s: %s", lookup[k].designation, windows_error_str(0));
 			lookup[k].list[0] = 0;
 		}
 	}
@@ -1342,7 +1342,7 @@
 		for (k = 0; k < 3; k++) {
 			j = get_sub_api(lookup[k].list, i);
 			if (j >= 0) {
-				usbi_dbg("matched %s name against %s", lookup[k].designation,
+				usbi_dbg(NULL, "matched %s name against %s", lookup[k].designation,
 					(i != USB_API_WINUSBX) ? usb_api_backend[i].designation : usb_api_backend[i].driver_name_list[j]);
 				*api = i;
 				*sub_api = j;
@@ -1378,7 +1378,7 @@
 	if (priv->usb_interface[interface_number].path != NULL) {
 		if (api == USB_API_HID) {
 			// HID devices can have multiple collections (COL##) for each MI_## interface
-			usbi_dbg("interface[%d] already set - ignoring HID collection: %s",
+			usbi_dbg(ctx, "interface[%d] already set - ignoring HID collection: %s",
 				interface_number, device_id);
 			return LIBUSB_ERROR_ACCESS;
 		}
@@ -1386,7 +1386,7 @@
 		safe_free(priv->usb_interface[interface_number].path);
 	}
 
-	usbi_dbg("interface[%d] = %s", interface_number, dev_interface_path);
+	usbi_dbg(ctx, "interface[%d] = %s", interface_number, dev_interface_path);
 	priv->usb_interface[interface_number].path = dev_interface_path;
 	priv->usb_interface[interface_number].apib = &usb_api_backend[api];
 	priv->usb_interface[interface_number].sub_api = sub_api;
@@ -1415,14 +1415,14 @@
 
 	for (i = 0; i < priv->hid->nb_interfaces; i++) {
 		if ((priv->usb_interface[i].path != NULL) && strcmp(priv->usb_interface[i].path, dev_interface_path) == 0) {
-			usbi_dbg("interface[%u] already set to %s", i, dev_interface_path);
+			usbi_dbg(ctx, "interface[%u] already set to %s", i, dev_interface_path);
 			return LIBUSB_ERROR_ACCESS;
 		}
 	}
 
 	priv->usb_interface[priv->hid->nb_interfaces].path = dev_interface_path;
 	priv->usb_interface[priv->hid->nb_interfaces].apib = &usb_api_backend[USB_API_HID];
-	usbi_dbg("interface[%u] = %s", priv->hid->nb_interfaces, dev_interface_path);
+	usbi_dbg(ctx, "interface[%u] = %s", priv->hid->nb_interfaces, dev_interface_path);
 	priv->hid->nb_interfaces++;
 	return LIBUSB_SUCCESS;
 }
@@ -1518,7 +1518,7 @@
 //#define ENUM_DEBUG
 #if defined(ENABLE_LOGGING) && defined(ENUM_DEBUG)
 		const char * const passname[] = {"HUB", "DEV", "HCD", "GEN", "HID", "EXT"};
-		usbi_dbg("#### PROCESSING %ss %s", passname[MIN(pass, EXT_PASS)], guid_to_string(guid_list[pass], guid_string));
+		usbi_dbg(ctx, "#### PROCESSING %ss %s", passname[MIN(pass, EXT_PASS)], guid_to_string(guid_list[pass], guid_string));
 #endif
 		if ((pass == HID_PASS) && (guid_list[HID_PASS] == NULL))
 			continue;
@@ -1570,7 +1570,7 @@
 			}
 
 #ifdef ENUM_DEBUG
-			usbi_dbg("PRO: %s", dev_id);
+			usbi_dbg(ctx, "PRO: %s", dev_id);
 #endif
 
 			// Set API to use or get additional data from generic pass
@@ -1593,7 +1593,7 @@
 						break;
 				}
 				if (j == nb_usb_enumerators) {
-					usbi_dbg("found new PnP enumerator string '%s'", enumerator);
+					usbi_dbg(ctx, "found new PnP enumerator string '%s'", enumerator);
 					if (nb_usb_enumerators < ARRAYSIZE(usb_enumerator)) {
 						usb_enumerator[nb_usb_enumerators] = _strdup(enumerator);
 						if (usb_enumerator[nb_usb_enumerators] != NULL) {
@@ -1661,7 +1661,7 @@
 								break;
 						}
 						if (j == nb_guids) {
-							usbi_dbg("extra GUID: %s", guid_string);
+							usbi_dbg(ctx, "extra GUID: %s", guid_string);
 							guid_list[nb_guids++] = if_guid;
 						} else {
 							// Duplicate, ignore
@@ -1703,7 +1703,7 @@
 						libusb_unref_device(dev);
 					}
 
-					usbi_dbg("unlisted ancestor for '%s' (non USB HID, newly connected, etc.) - ignoring", dev_id);
+					usbi_dbg(ctx, "unlisted ancestor for '%s' (non USB HID, newly connected, etc.) - ignoring", dev_id);
 					continue;
 				}
 
@@ -1722,7 +1722,7 @@
 				dev = usbi_get_device_by_session_id(ctx, session_id);
 				if (dev == NULL) {
 				alloc_device:
-					usbi_dbg("allocating new device for session [%lX]", session_id);
+					usbi_dbg(ctx, "allocating new device for session [%lX]", session_id);
 					dev = usbi_alloc_device(ctx, session_id);
 					if (dev == NULL)
 						LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
@@ -1735,17 +1735,17 @@
 						LOOP_BREAK(LIBUSB_ERROR_NO_MEM);
 					}
 				} else {
-					usbi_dbg("found existing device for session [%lX]", session_id);
+					usbi_dbg(ctx, "found existing device for session [%lX]", session_id);
 
 					priv = usbi_get_device_priv(dev);
 					if (strcmp(priv->dev_id, dev_id) != 0) {
-						usbi_dbg("device instance ID for session [%lX] changed", session_id);
+						usbi_dbg(ctx, "device instance ID for session [%lX] changed", session_id);
 						usbi_disconnect_device(dev);
 						libusb_unref_device(dev);
 						goto alloc_device;
 					}
 					if (!IsEqualGUID(&priv->class_guid, &dev_info_data.ClassGuid)) {
-						usbi_dbg("device class GUID for session [%lX] changed", session_id);
+						usbi_dbg(ctx, "device class GUID for session [%lX] changed", session_id);
 						usbi_disconnect_device(dev);
 						libusb_unref_device(dev);
 						goto alloc_device;
@@ -1824,10 +1824,10 @@
 			default: // HID_PASS and later
 				if (parent_priv->apib->id == USB_API_HID || parent_priv->apib->id == USB_API_COMPOSITE) {
 					if (parent_priv->apib->id == USB_API_HID) {
-						usbi_dbg("setting HID interface for [%lX]:", parent_dev->session_data);
+						usbi_dbg(ctx, "setting HID interface for [%lX]:", parent_dev->session_data);
 						r = set_hid_interface(ctx, parent_dev, dev_interface_path);
 					} else {
-						usbi_dbg("setting composite interface for [%lX]:", parent_dev->session_data);
+						usbi_dbg(ctx, "setting composite interface for [%lX]:", parent_dev->session_data);
 						r = set_composite_interface(ctx, parent_dev, dev_interface_path, dev_id, api, sub_api);
 					}
 					switch (r) {
@@ -2338,10 +2338,10 @@
 			KLIB_VERSION LibK_Version;
 
 			pLibK_GetVersion(&LibK_Version);
-			usbi_dbg("libusbK DLL found, version: %d.%d.%d.%d", LibK_Version.Major, LibK_Version.Minor,
+			usbi_dbg(ctx, "libusbK DLL found, version: %d.%d.%d.%d", LibK_Version.Major, LibK_Version.Minor,
 				LibK_Version.Micro, LibK_Version.Nano);
 		} else {
-			usbi_dbg("libusbK DLL found, version unknown");
+			usbi_dbg(ctx, "libusbK DLL found, version unknown");
 		}
 
 		pLibK_GetProcAddress = (LibK_GetProcAddress_t)GetProcAddress(hlibusbK, "LibK_GetProcAddress");
@@ -2520,7 +2520,7 @@
 		endpoint_address = (i == -1) ? 0 : priv->usb_interface[iface].endpoint[i];
 		if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
 			PIPE_TRANSFER_TIMEOUT, sizeof(ULONG), &timeout))
-			usbi_dbg("failed to set PIPE_TRANSFER_TIMEOUT for control endpoint %02X", endpoint_address);
+			usbi_dbg(HANDLE_CTX(dev_handle), "failed to set PIPE_TRANSFER_TIMEOUT for control endpoint %02X", endpoint_address);
 
 		if ((i == -1) || (sub_api == SUB_API_LIBUSB0))
 			continue; // Other policies don't apply to control endpoint or libusb0
@@ -2529,27 +2529,27 @@
 		handle_priv->interface_handle[iface].zlp[endpoint_address] = WINUSB_ZLP_UNSET;
 		if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
 			SHORT_PACKET_TERMINATE, sizeof(UCHAR), &policy))
-			usbi_dbg("failed to disable SHORT_PACKET_TERMINATE for endpoint %02X", endpoint_address);
+			usbi_dbg(HANDLE_CTX(dev_handle), "failed to disable SHORT_PACKET_TERMINATE for endpoint %02X", endpoint_address);
 
 		if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
 			IGNORE_SHORT_PACKETS, sizeof(UCHAR), &policy))
-			usbi_dbg("failed to disable IGNORE_SHORT_PACKETS for endpoint %02X", endpoint_address);
+			usbi_dbg(HANDLE_CTX(dev_handle), "failed to disable IGNORE_SHORT_PACKETS for endpoint %02X", endpoint_address);
 
 		policy = true;
 		/* ALLOW_PARTIAL_READS must be enabled due to likely libusbK bug. See:
 		   https://sourceforge.net/mailarchive/message.php?msg_id=29736015 */
 		if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
 			ALLOW_PARTIAL_READS, sizeof(UCHAR), &policy))
-			usbi_dbg("failed to enable ALLOW_PARTIAL_READS for endpoint %02X", endpoint_address);
+			usbi_dbg(HANDLE_CTX(dev_handle), "failed to enable ALLOW_PARTIAL_READS for endpoint %02X", endpoint_address);
 
 		if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
 			AUTO_CLEAR_STALL, sizeof(UCHAR), &policy))
-			usbi_dbg("failed to enable AUTO_CLEAR_STALL for endpoint %02X", endpoint_address);
+			usbi_dbg(HANDLE_CTX(dev_handle), "failed to enable AUTO_CLEAR_STALL for endpoint %02X", endpoint_address);
 
 		if (sub_api == SUB_API_LIBUSBK) {
 			if (!WinUSBX[sub_api].SetPipePolicy(winusb_handle, endpoint_address,
 				ISO_ALWAYS_START_ASAP, sizeof(UCHAR), &policy))
-				usbi_dbg("failed to enable ISO_ALWAYS_START_ASAP for endpoint %02X", endpoint_address);
+				usbi_dbg(HANDLE_CTX(dev_handle), "failed to enable ISO_ALWAYS_START_ASAP for endpoint %02X", endpoint_address);
 		}
 	}
 
@@ -2667,7 +2667,7 @@
 		}
 		handle_priv->interface_handle[iface].dev_handle = handle_priv->interface_handle[0].dev_handle;
 	}
-	usbi_dbg("claimed interface %u", iface);
+	usbi_dbg(ctx, "claimed interface %u", iface);
 	handle_priv->active_interface = iface;
 
 	return LIBUSB_SUCCESS;
@@ -2701,7 +2701,7 @@
 	int i;
 
 	if ((api_id < USB_API_WINUSBX) || (api_id > USB_API_HID)) {
-		usbi_dbg("unsupported API ID");
+		usbi_dbg(HANDLE_CTX(dev_handle), "unsupported API ID");
 		return -1;
 	}
 
@@ -2727,7 +2727,7 @@
 		return -1;
 
 	if ((api_id < USB_API_WINUSBX) || (api_id > USB_API_HID)) {
-		usbi_dbg("unsupported API ID");
+		usbi_dbg(HANDLE_CTX(dev_handle), "unsupported API ID");
 		return -1;
 	}
 
@@ -2792,7 +2792,7 @@
 			return LIBUSB_ERROR_NOT_FOUND;
 	}
 
-	usbi_dbg("will use interface %d", current_interface);
+	usbi_dbg(ITRANSFER_CTX(itransfer), "will use interface %d", current_interface);
 
 	winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
 	set_transfer_priv_handle(itransfer, handle_priv->interface_handle[current_interface].dev_handle);
@@ -2894,7 +2894,7 @@
 		return LIBUSB_ERROR_NOT_FOUND;
 	}
 
-	usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
+	usbi_dbg(TRANSFER_CTX(transfer), "matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
 
 	winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
 	set_transfer_priv_handle(itransfer, handle_priv->interface_handle[current_interface].dev_handle);
@@ -2928,10 +2928,10 @@
 		}
 
 		if (IS_XFERIN(transfer)) {
-			usbi_dbg("reading %d iso packets", transfer->num_iso_packets);
+			usbi_dbg(TRANSFER_CTX(transfer), "reading %d iso packets", transfer->num_iso_packets);
 			ret = WinUSBX[sub_api].IsoReadPipe(winusb_handle, transfer->endpoint, transfer->buffer, transfer->length, overlapped, iso_context);
 		} else {
-			usbi_dbg("writing %d iso packets", transfer->num_iso_packets);
+			usbi_dbg(TRANSFER_CTX(transfer), "writing %d iso packets", transfer->num_iso_packets);
 			ret = WinUSBX[sub_api].IsoWritePipe(winusb_handle, transfer->endpoint, transfer->buffer, transfer->length, overlapped, iso_context);
 		}
 
@@ -3084,14 +3084,14 @@
 		return LIBUSB_ERROR_NOT_FOUND;
 	}
 
-	usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
+	usbi_dbg(TRANSFER_CTX(transfer), "matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
 
 	winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
 	set_transfer_priv_handle(itransfer, handle_priv->interface_handle[current_interface].dev_handle);
 	overlapped = get_transfer_priv_overlapped(itransfer);
 
 	if (IS_XFERIN(transfer)) {
-		usbi_dbg("reading %d bytes", transfer->length);
+		usbi_dbg(TRANSFER_CTX(transfer), "reading %d bytes", transfer->length);
 		ret = WinUSBX[sub_api].ReadPipe(winusb_handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, overlapped);
 	} else {
 		// Set SHORT_PACKET_TERMINATE if ZLP requested.
@@ -3111,7 +3111,7 @@
 			return LIBUSB_ERROR_NOT_SUPPORTED;
 		}
 
-		usbi_dbg("writing %d bytes", transfer->length);
+		usbi_dbg(TRANSFER_CTX(transfer), "writing %d bytes", transfer->length);
 		ret = WinUSBX[sub_api].WritePipe(winusb_handle, transfer->endpoint, transfer->buffer, transfer->length, NULL, overlapped);
 	}
 
@@ -3140,7 +3140,7 @@
 		return LIBUSB_ERROR_NOT_FOUND;
 	}
 
-	usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
+	usbi_dbg(HANDLE_CTX(dev_handle), "matched endpoint %02X with interface %d", endpoint, current_interface);
 	winusb_handle = handle_priv->interface_handle[current_interface].api_handle;
 
 	if (!WinUSBX[sub_api].ResetPipe(winusb_handle, endpoint)) {
@@ -3162,7 +3162,7 @@
 
 	CHECK_WINUSBX_AVAILABLE(sub_api);
 
-	usbi_dbg("will use interface %d", current_interface);
+	usbi_dbg(TRANSFER_CTX(transfer), "will use interface %d", current_interface);
 
 	handle = handle_priv->interface_handle[current_interface].api_handle;
 	if (!WinUSBX[sub_api].AbortPipe(handle, transfer->endpoint)) {
@@ -3196,7 +3196,7 @@
 		winusb_handle = handle_priv->interface_handle[i].api_handle;
 		if (HANDLE_VALID(winusb_handle)) {
 			for (j = 0; j < priv->usb_interface[i].nb_endpoints; j++) {
-				usbi_dbg("resetting ep %02X", priv->usb_interface[i].endpoint[j]);
+				usbi_dbg(HANDLE_CTX(dev_handle), "resetting ep %02X", priv->usb_interface[i].endpoint[j]);
 				if (!WinUSBX[sub_api].AbortPipe(winusb_handle, priv->usb_interface[i].endpoint[j]))
 					usbi_err(HANDLE_CTX(dev_handle), "AbortPipe (pipe address %02X) failed: %s",
 						priv->usb_interface[i].endpoint[j], windows_error_str(0));
@@ -3532,28 +3532,28 @@
 
 	switch (type) {
 	case LIBUSB_DT_DEVICE:
-		usbi_dbg("LIBUSB_DT_DEVICE");
+		usbi_dbg(DEVICE_CTX(dev), "LIBUSB_DT_DEVICE");
 		return _hid_get_device_descriptor(priv->hid, data, size);
 	case LIBUSB_DT_CONFIG:
-		usbi_dbg("LIBUSB_DT_CONFIG");
+		usbi_dbg(DEVICE_CTX(dev), "LIBUSB_DT_CONFIG");
 		if (!_index)
 			return _hid_get_config_descriptor(priv->hid, data, size);
 		return LIBUSB_ERROR_INVALID_PARAM;
 	case LIBUSB_DT_STRING:
-		usbi_dbg("LIBUSB_DT_STRING");
+		usbi_dbg(DEVICE_CTX(dev), "LIBUSB_DT_STRING");
 		return _hid_get_string_descriptor(priv->hid, _index, data, size, hid_handle);
 	case LIBUSB_DT_HID:
-		usbi_dbg("LIBUSB_DT_HID");
+		usbi_dbg(DEVICE_CTX(dev), "LIBUSB_DT_HID");
 		if (!_index)
 			return _hid_get_hid_descriptor(priv->hid, data, size);
 		return LIBUSB_ERROR_INVALID_PARAM;
 	case LIBUSB_DT_REPORT:
-		usbi_dbg("LIBUSB_DT_REPORT");
+		usbi_dbg(DEVICE_CTX(dev), "LIBUSB_DT_REPORT");
 		if (!_index)
 			return _hid_get_report_descriptor(priv->hid, data, size);
 		return LIBUSB_ERROR_INVALID_PARAM;
 	case LIBUSB_DT_PHYSICAL:
-		usbi_dbg("LIBUSB_DT_PHYSICAL");
+		usbi_dbg(DEVICE_CTX(dev), "LIBUSB_DT_PHYSICAL");
 		if (HidD_GetPhysicalDescriptor(hid_handle, data, (ULONG)*size))
 			return LIBUSB_COMPLETED;
 		return LIBUSB_ERROR_OTHER;
@@ -3595,7 +3595,7 @@
 		return LIBUSB_ERROR_NO_MEM;
 
 	buf[0] = (uint8_t)id; // Must be set always
-	usbi_dbg("report ID: 0x%02X", buf[0]);
+	usbi_dbg(DEVICE_CTX(dev), "report ID: 0x%02X", buf[0]);
 
 	// NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0)
 	if (!DeviceIoControl(hid_handle, ioctl_code, buf, expected_size + 1,
@@ -3643,7 +3643,7 @@
 		return LIBUSB_ERROR_INVALID_PARAM;
 	}
 
-	usbi_dbg("report ID: 0x%02X", id);
+	usbi_dbg(DEVICE_CTX(dev), "report ID: 0x%02X", id);
 	// When report IDs are not used (i.e. when id == 0), we must add
 	// a null report ID. Otherwise, we just use original data buffer
 	if (id == 0)
@@ -3802,7 +3802,7 @@
 
 		// Set the maximum available input buffer size
 		for (i = 32; HidD_SetNumInputBuffers(hid_handle, i); i *= 2);
-		usbi_dbg("set maximum input buffer size to %d", i / 2);
+		usbi_dbg(HANDLE_CTX(dev_handle), "set maximum input buffer size to %d", i / 2);
 
 		// Get the maximum input and output report size
 		if (!HidD_GetPreparsedData(hid_handle, &preparsed_data) || !preparsed_data) {
@@ -3819,7 +3819,7 @@
 		size[1] = capabilities.NumberOutputValueCaps;
 		size[2] = capabilities.NumberFeatureValueCaps;
 		for (j = HidP_Input; j <= HidP_Feature; j++) {
-			usbi_dbg("%lu HID %s report value(s) found", ULONG_CAST(size[j]), type[j]);
+			usbi_dbg(HANDLE_CTX(dev_handle), "%lu HID %s report value(s) found", ULONG_CAST(size[j]), type[j]);
 			priv->hid->uses_report_ids[j] = false;
 			if (size[j] > 0) {
 				value_caps = calloc(size[j], sizeof(HIDP_VALUE_CAPS));
@@ -3829,7 +3829,7 @@
 					nb_ids[0] = 0;
 					nb_ids[1] = 0;
 					for (i = 0; i < (int)size[j]; i++) {
-						usbi_dbg("  Report ID: 0x%02X", value_caps[i].ReportID);
+						usbi_dbg(HANDLE_CTX(dev_handle), "  Report ID: 0x%02X", value_caps[i].ReportID);
 						if (value_caps[i].ReportID != 0)
 							nb_ids[1]++;
 						else
@@ -3922,7 +3922,7 @@
 
 	handle_priv->interface_handle[iface].dev_handle = INTERFACE_CLAIMED;
 
-	usbi_dbg("claimed interface %u", iface);
+	usbi_dbg(HANDLE_CTX(dev_handle), "claimed interface %u", iface);
 	handle_priv->active_interface = iface;
 
 	return LIBUSB_SUCCESS;
@@ -3993,7 +3993,7 @@
 			return LIBUSB_ERROR_NOT_FOUND;
 	}
 
-	usbi_dbg("will use interface %d", current_interface);
+	usbi_dbg(ITRANSFER_CTX(itransfer), "will use interface %d", current_interface);
 
 	hid_handle = handle_priv->interface_handle[current_interface].api_handle;
 	set_transfer_priv_handle(itransfer, hid_handle);
@@ -4088,7 +4088,7 @@
 		return LIBUSB_ERROR_NOT_FOUND;
 	}
 
-	usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
+	usbi_dbg(TRANSFER_CTX(transfer), "matched endpoint %02X with interface %d", transfer->endpoint, current_interface);
 
 	hid_handle = handle_priv->interface_handle[current_interface].api_handle;
 	set_transfer_priv_handle(itransfer, hid_handle);
@@ -4111,7 +4111,7 @@
 
 	if (direction_in) {
 		transfer_priv->hid_dest = transfer->buffer;
-		usbi_dbg("reading %d bytes (report ID: 0x00)", length);
+		usbi_dbg(TRANSFER_CTX(transfer), "reading %d bytes (report ID: 0x00)", length);
 		ret = ReadFile(hid_handle, transfer_priv->hid_buffer, length + 1, NULL, overlapped);
 	} else {
 		if (!priv->hid->uses_report_ids[1])
@@ -4120,7 +4120,7 @@
 			// We could actually do without the calloc and memcpy in this case
 			memcpy(transfer_priv->hid_buffer, transfer->buffer, transfer->length);
 
-		usbi_dbg("writing %d bytes (report ID: 0x%02X)", length, transfer_priv->hid_buffer[0]);
+		usbi_dbg(TRANSFER_CTX(transfer), "writing %d bytes (report ID: 0x%02X)", length, transfer_priv->hid_buffer[0]);
 		ret = WriteFile(hid_handle, transfer_priv->hid_buffer, length, NULL, overlapped);
 	}
 
@@ -4170,7 +4170,7 @@
 		return LIBUSB_ERROR_NOT_FOUND;
 	}
 
-	usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface);
+	usbi_dbg(HANDLE_CTX(dev_handle), "matched endpoint %02X with interface %d", endpoint, current_interface);
 	hid_handle = handle_priv->interface_handle[current_interface].api_handle;
 
 	// No endpoint selection with Microsoft's implementation, so we try to flush the
@@ -4267,7 +4267,7 @@
 		// open HID devices with a U2F usage unless running as administrator. We ignore this
 		// failure and proceed without the HID device opened.
 		if (r == LIBUSB_ERROR_ACCESS) {
-			usbi_dbg("ignoring access denied error while opening HID interface of composite device");
+			usbi_dbg(HANDLE_CTX(dev_handle), "ignoring access denied error while opening HID interface of composite device");
 			r = LIBUSB_SUCCESS;
 		}
 	}
@@ -4376,7 +4376,7 @@
 
 	// Try and target a specific interface if the control setup indicates such
 	if ((iface >= 0) && (iface < USB_MAXINTERFACES)) {
-		usbi_dbg("attempting control transfer targeted to interface %d", iface);
+		usbi_dbg(TRANSFER_CTX(transfer), "attempting control transfer targeted to interface %d", iface);
 		if ((priv->usb_interface[iface].path != NULL)
 				&& (priv->usb_interface[iface].apib->submit_control_transfer != NULL)) {
 			r = priv->usb_interface[iface].apib->submit_control_transfer(priv->usb_interface[iface].sub_api, itransfer);
@@ -4392,10 +4392,10 @@
 			if ((priv->usb_interface[iface].path != NULL)
 					&& (priv->usb_interface[iface].apib->submit_control_transfer != NULL)) {
 				if ((pass == 0) && (priv->usb_interface[iface].restricted_functionality)) {
-					usbi_dbg("trying to skip restricted interface #%d (HID keyboard or mouse?)", iface);
+					usbi_dbg(TRANSFER_CTX(transfer), "trying to skip restricted interface #%d (HID keyboard or mouse?)", iface);
 					continue;
 				}
-				usbi_dbg("using interface %d", iface);
+				usbi_dbg(TRANSFER_CTX(transfer), "using interface %d", iface);
 				r = priv->usb_interface[iface].apib->submit_control_transfer(priv->usb_interface[iface].sub_api, itransfer);
 				// If not supported on this API, it may be supported on another, so don't give up yet!!
 				if (r == LIBUSB_ERROR_NOT_SUPPORTED)
diff --git a/libusb/os/windows_winusb.h b/libusb/os/windows_winusb.h
index 6646dc7..6afd5cb 100644
--- a/libusb/os/windows_winusb.h
+++ b/libusb/os/windows_winusb.h
@@ -96,7 +96,7 @@
 extern const struct windows_usb_api_backend usb_api_backend[USB_API_MAX];
 
 #define PRINT_UNSUPPORTED_API(fname)				\
-	usbi_dbg("unsupported API call for '%s' "		\
+	usbi_dbg(NULL, "unsupported API call for '%s' "		\
 		"(unrecognized device driver)", #fname)
 
 #define CHECK_SUPPORTED_API(apip, fname)			\
diff --git a/libusb/sync.c b/libusb/sync.c
index adc95b4..1fa1f0b 100644
--- a/libusb/sync.c
+++ b/libusb/sync.c
@@ -36,7 +36,7 @@
 {
 	int *completed = transfer->user_data;
 	*completed = 1;
-	usbi_dbg("actual_length=%d", transfer->actual_length);
+	usbi_dbg(TRANSFER_CTX(transfer), "actual_length=%d", transfer->actual_length);
 	/* caller interprets result and frees transfer */
 }
 
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index 4116e1d..fa21711 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 11640
+#define LIBUSB_NANO 11641