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

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