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

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