Blame SOURCES/0010-linux_usbfs-Wait-until-all-URBs-have-been-reaped-bef.patch

d5e699
From e0a164b50a1f11ead9f47da0233f6f954e04127f Mon Sep 17 00:00:00 2001
d5e699
From: Chris Dickens <christopher.a.dickens@gmail.com>
d5e699
Date: Thu, 16 Jan 2020 14:17:12 -0800
d5e699
Subject: [PATCH 10/10] linux_usbfs: Wait until all URBs have been reaped
d5e699
 before freeing them
d5e699
d5e699
Prior to this change, the URBs allocated for an individual transfer were
d5e699
freed when the last URB in the transfer was reaped. Normally this causes
d5e699
no issues because URBs are reaped in the order they were submitted. If
d5e699
the device is disconnected while multiple URBs are queued, these URBs
d5e699
may be reaped in an order that does not match that of submission.
d5e699
d5e699
Change the logic to free the URBs when all the URBs of a transfer have
d5e699
been reaped rather than the last one. While in here, improve some debug
d5e699
messages.
d5e699
d5e699
Closes #607
d5e699
d5e699
Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
d5e699
(cherry picked from commit 9eda802d947d9c4212eb3f821fa51956029dade0)
d5e699
---
d5e699
 libusb/os/linux_usbfs.c | 60 ++++++++++++++++++++---------------------
d5e699
 libusb/version_nano.h   |  2 +-
d5e699
 2 files changed, 31 insertions(+), 31 deletions(-)
d5e699
d5e699
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
d5e699
index 53530cd..4179b9a 100644
d5e699
--- a/libusb/os/linux_usbfs.c
d5e699
+++ b/libusb/os/linux_usbfs.c
d5e699
@@ -944,7 +944,7 @@ static int usbfs_get_active_config(struct libusb_device *dev, int fd)
d5e699
 
d5e699
 		/* we hit this error path frequently with buggy devices :( */
d5e699
 		usbi_warn(DEVICE_CTX(dev),
d5e699
-			"get_configuration failed ret=%d errno=%d", r, errno);
d5e699
+			"get configuration failed, errno=%d", errno);
d5e699
 		priv->active_config = -1;
d5e699
 	} else {
d5e699
 		if (active_config > 0) {
d5e699
@@ -1401,7 +1401,7 @@ static int initialize_handle(struct libusb_device_handle *handle, int fd)
d5e699
 		if (errno == ENOTTY)
d5e699
 			usbi_dbg("getcap not available");
d5e699
 		else
d5e699
-			usbi_err(HANDLE_CTX(handle), "getcap failed (%d)", errno);
d5e699
+			usbi_err(HANDLE_CTX(handle), "getcap failed, errno=%d", errno);
d5e699
 		hpriv->caps = 0;
d5e699
 		if (supports_flag_zero_packet)
d5e699
 			hpriv->caps |= USBFS_CAP_ZERO_PACKET;
d5e699
@@ -1426,7 +1426,7 @@ static int op_wrap_sys_device(struct libusb_context *ctx,
d5e699
 	if (r < 0) {
d5e699
 		r = ioctl(fd, IOCTL_USBFS_CONNECTINFO, &ci);
d5e699
 		if (r < 0) {
d5e699
-			usbi_err(ctx, "connectinfo failed (%d)", errno);
d5e699
+			usbi_err(ctx, "connectinfo failed, errno=%d", errno);
d5e699
 			return LIBUSB_ERROR_IO;
d5e699
 		}
d5e699
 		/* There is no ioctl to get the bus number. We choose 0 here
d5e699
@@ -1537,7 +1537,8 @@ static int op_set_configuration(struct libusb_device_handle *handle, int config)
d5e699
 		else if (errno == ENODEV)
d5e699
 			return LIBUSB_ERROR_NO_DEVICE;
d5e699
 
d5e699
-		usbi_err(HANDLE_CTX(handle), "failed, error %d errno %d", r, errno);
d5e699
+		usbi_err(HANDLE_CTX(handle),
d5e699
+			"set configuration failed, errno=%d", errno);
d5e699
 		return LIBUSB_ERROR_OTHER;
d5e699
 	}
d5e699
 
d5e699
@@ -1560,7 +1561,7 @@ static int claim_interface(struct libusb_device_handle *handle, int iface)
d5e699
 			return LIBUSB_ERROR_NO_DEVICE;
d5e699
 
d5e699
 		usbi_err(HANDLE_CTX(handle),
d5e699
-			"claim interface failed, error %d errno %d", r, errno);
d5e699
+			"claim interface failed, errno=%d", errno);
d5e699
 		return LIBUSB_ERROR_OTHER;
d5e699
 	}
d5e699
 	return 0;
d5e699
@@ -1575,7 +1576,7 @@ static int release_interface(struct libusb_device_handle *handle, int iface)
d5e699
 			return LIBUSB_ERROR_NO_DEVICE;
d5e699
 
d5e699
 		usbi_err(HANDLE_CTX(handle),
d5e699
-			"release interface failed, error %d errno %d", r, errno);
d5e699
+			"release interface failed, errno=%d", errno);
d5e699
 		return LIBUSB_ERROR_OTHER;
d5e699
 	}
d5e699
 	return 0;
d5e699
@@ -1598,7 +1599,7 @@ static int op_set_interface(struct libusb_device_handle *handle, int iface,
d5e699
 			return LIBUSB_ERROR_NO_DEVICE;
d5e699
 
d5e699
 		usbi_err(HANDLE_CTX(handle),
d5e699
-			"setintf failed error %d errno %d", r, errno);
d5e699
+			"set interface failed, errno=%d", errno);
d5e699
 		return LIBUSB_ERROR_OTHER;
d5e699
 	}
d5e699
 
d5e699
@@ -1618,7 +1619,7 @@ static int op_clear_halt(struct libusb_device_handle *handle,
d5e699
 			return LIBUSB_ERROR_NO_DEVICE;
d5e699
 
d5e699
 		usbi_err(HANDLE_CTX(handle),
d5e699
-			"clear_halt failed error %d errno %d", r, errno);
d5e699
+			"clear halt failed, errno=%d", errno);
d5e699
 		return LIBUSB_ERROR_OTHER;
d5e699
 	}
d5e699
 
d5e699
@@ -1650,7 +1651,7 @@ static int op_reset_device(struct libusb_device_handle *handle)
d5e699
 		}
d5e699
 
d5e699
 		usbi_err(HANDLE_CTX(handle),
d5e699
-			"reset failed error %d errno %d", r, errno);
d5e699
+			"reset failed, errno=%d", errno);
d5e699
 		ret = LIBUSB_ERROR_OTHER;
d5e699
 		goto out;
d5e699
 	}
d5e699
@@ -1708,7 +1709,7 @@ static int do_streams_ioctl(struct libusb_device_handle *handle, long req,
d5e699
 			return LIBUSB_ERROR_NO_DEVICE;
d5e699
 
d5e699
 		usbi_err(HANDLE_CTX(handle),
d5e699
-			"streams-ioctl failed error %d errno %d", r, errno);
d5e699
+			"streams-ioctl failed, errno=%d", errno);
d5e699
 		return LIBUSB_ERROR_OTHER;
d5e699
 	}
d5e699
 	return r;
d5e699
@@ -1770,7 +1771,7 @@ static int op_kernel_driver_active(struct libusb_device_handle *handle,
d5e699
 			return LIBUSB_ERROR_NO_DEVICE;
d5e699
 
d5e699
 		usbi_err(HANDLE_CTX(handle),
d5e699
-			"get driver failed error %d errno %d", r, errno);
d5e699
+			"get driver failed, errno=%d", errno);
d5e699
 		return LIBUSB_ERROR_OTHER;
d5e699
 	}
d5e699
 
d5e699
@@ -1804,7 +1805,7 @@ static int op_detach_kernel_driver(struct libusb_device_handle *handle,
d5e699
 			return LIBUSB_ERROR_NO_DEVICE;
d5e699
 
d5e699
 		usbi_err(HANDLE_CTX(handle),
d5e699
-			"detach failed error %d errno %d", r, errno);
d5e699
+			"detach failed, errno=%d", errno);
d5e699
 		return LIBUSB_ERROR_OTHER;
d5e699
 	}
d5e699
 
d5e699
@@ -1834,7 +1835,7 @@ static int op_attach_kernel_driver(struct libusb_device_handle *handle,
d5e699
 			return LIBUSB_ERROR_BUSY;
d5e699
 
d5e699
 		usbi_err(HANDLE_CTX(handle),
d5e699
-			"attach failed error %d errno %d", r, errno);
d5e699
+			"attach failed, errno=%d", errno);
d5e699
 		return LIBUSB_ERROR_OTHER;
d5e699
 	} else if (r == 0) {
d5e699
 		return LIBUSB_ERROR_NOT_FOUND;
d5e699
@@ -1863,7 +1864,7 @@ static int detach_kernel_driver_and_claim(struct libusb_device_handle *handle,
d5e699
 			return LIBUSB_ERROR_NO_DEVICE;
d5e699
 		}
d5e699
 		usbi_err(HANDLE_CTX(handle),
d5e699
-			"disconnect-and-claim failed errno %d", errno);
d5e699
+			"disconnect-and-claim failed, errno=%d", errno);
d5e699
 		return LIBUSB_ERROR_OTHER;
d5e699
 	} else if (r == 0)
d5e699
 		return 0;
d5e699
@@ -2083,7 +2084,7 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer)
d5e699
 				r = LIBUSB_ERROR_NO_MEM;
d5e699
 			} else {
d5e699
 				usbi_err(TRANSFER_CTX(transfer),
d5e699
-					"submiturb failed error %d errno=%d", r, errno);
d5e699
+					"submiturb failed, errno=%d", errno);
d5e699
 				r = LIBUSB_ERROR_IO;
d5e699
 			}
d5e699
 
d5e699
@@ -2241,7 +2242,7 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer)
d5e699
 				r = LIBUSB_ERROR_INVALID_PARAM;
d5e699
 			} else {
d5e699
 				usbi_err(TRANSFER_CTX(transfer),
d5e699
-					"submiturb failed error %d errno=%d", r, errno);
d5e699
+					"submiturb failed, errno=%d", errno);
d5e699
 				r = LIBUSB_ERROR_IO;
d5e699
 			}
d5e699
 
d5e699
@@ -2316,7 +2317,7 @@ static int submit_control_transfer(struct usbi_transfer *itransfer)
d5e699
 			return LIBUSB_ERROR_NO_DEVICE;
d5e699
 
d5e699
 		usbi_err(TRANSFER_CTX(transfer),
d5e699
-			"submiturb failed error %d errno=%d", r, errno);
d5e699
+			"submiturb failed, errno=%d", errno);
d5e699
 		return LIBUSB_ERROR_IO;
d5e699
 	}
d5e699
 	return 0;
d5e699
@@ -2498,10 +2499,10 @@ static int handle_bulk_completion(struct usbi_transfer *itransfer,
d5e699
 		goto cancel_remaining;
d5e699
 	}
d5e699
 
d5e699
-	/* if we're the last urb or we got less data than requested then we're
d5e699
+	/* if we've reaped all urbs or we got less data than requested then we're
d5e699
 	 * done */
d5e699
-	if (urb_idx == tpriv->num_urbs - 1) {
d5e699
-		usbi_dbg("last URB in transfer --> complete!");
d5e699
+	if (tpriv->num_retired == tpriv->num_urbs) {
d5e699
+		usbi_dbg("all URBs in transfer reaped --> complete!");
d5e699
 		goto completed;
d5e699
 	} else if (urb->actual_length < urb->buffer_length) {
d5e699
 		usbi_dbg("short transfer %d/%d --> complete!",
d5e699
@@ -2577,15 +2578,15 @@ static int handle_iso_completion(struct usbi_transfer *itransfer,
d5e699
 			break;
d5e699
 		case -ENODEV:
d5e699
 		case -ESHUTDOWN:
d5e699
-			usbi_dbg("device removed");
d5e699
+			usbi_dbg("packet %d - device removed", i);
d5e699
 			lib_desc->status = LIBUSB_TRANSFER_NO_DEVICE;
d5e699
 			break;
d5e699
 		case -EPIPE:
d5e699
-			usbi_dbg("detected endpoint stall");
d5e699
+			usbi_dbg("packet %d - detected endpoint stall", i);
d5e699
 			lib_desc->status = LIBUSB_TRANSFER_STALL;
d5e699
 			break;
d5e699
 		case -EOVERFLOW:
d5e699
-			usbi_dbg("overflow error");
d5e699
+			usbi_dbg("packet %d - overflow error", i);
d5e699
 			lib_desc->status = LIBUSB_TRANSFER_OVERFLOW;
d5e699
 			break;
d5e699
 		case -ETIME:
d5e699
@@ -2594,12 +2595,12 @@ static int handle_iso_completion(struct usbi_transfer *itransfer,
d5e699
 		case -ECOMM:
d5e699
 		case -ENOSR:
d5e699
 		case -EXDEV:
d5e699
-			usbi_dbg("low-level USB error %d", urb_desc->status);
d5e699
+			usbi_dbg("packet %d - low-level USB error %d", i, urb_desc->status);
d5e699
 			lib_desc->status = LIBUSB_TRANSFER_ERROR;
d5e699
 			break;
d5e699
 		default:
d5e699
 			usbi_warn(TRANSFER_CTX(transfer),
d5e699
-				"unrecognised urb status %d", urb_desc->status);
d5e699
+				"packet %d - unrecognised urb status %d", i, urb_desc->status);
d5e699
 			lib_desc->status = LIBUSB_TRANSFER_ERROR;
d5e699
 			break;
d5e699
 		}
d5e699
@@ -2643,9 +2644,9 @@ static int handle_iso_completion(struct usbi_transfer *itransfer,
d5e699
 		break;
d5e699
 	}
d5e699
 
d5e699
-	/* if we're the last urb then we're done */
d5e699
-	if (urb_idx == num_urbs) {
d5e699
-		usbi_dbg("last URB in transfer --> complete!");
d5e699
+	/* if we've reaped all urbs then we're done */
d5e699
+	if (tpriv->num_retired == num_urbs) {
d5e699
+		usbi_dbg("all URBs in transfer reaped --> complete!");
d5e699
 		free_iso_urbs(tpriv);
d5e699
 		usbi_mutex_unlock(&itransfer->lock);
d5e699
 		return usbi_handle_transfer_completion(itransfer, status);
d5e699
@@ -2733,8 +2734,7 @@ static int reap_for_handle(struct libusb_device_handle *handle)
d5e699
 		if (errno == ENODEV)
d5e699
 			return LIBUSB_ERROR_NO_DEVICE;
d5e699
 
d5e699
-		usbi_err(HANDLE_CTX(handle), "reap failed error %d errno=%d",
d5e699
-			r, errno);
d5e699
+		usbi_err(HANDLE_CTX(handle), "reap failed, errno=%d", errno);
d5e699
 		return LIBUSB_ERROR_IO;
d5e699
 	}
d5e699
 
d5e699
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
d5e699
index 3247cec..f496998 100644
d5e699
--- a/libusb/version_nano.h
d5e699
+++ b/libusb/version_nano.h
d5e699
@@ -1 +1 @@
d5e699
-#define LIBUSB_NANO 11427
d5e699
+#define LIBUSB_NANO 11428
d5e699
-- 
d5e699
2.26.1
d5e699