Skip to content

Commit 7c00af4

Browse files
janherlingmetameta-codesync[bot]
authored andcommitted
Ocean: Filter by endpoint address on the SuperSpeed companion-descriptor path too
Summary: Inside the per-endpoint loop of `determineIsochronousTransferLayout()` only the fallback branch checked the endpoint address. The SuperSpeed branch assigned `endpointPacketSize = endpointCompanionDescriptor->wBytesPerInterval` for whichever endpoint it was looking at, with no address check and no `break`. On a SuperSpeed link every endpoint carries a companion descriptor, so that branch is the one taken for all of them and the loop simply kept overwriting the value. The packet size therefore came from the *last* endpoint of the altsetting rather than from the one whose `bEndpointAddress` matches the requested `endpointAddress`, which the header documents as "The address of the endpoint on which the transfer will happen". The address filter is now applied once, ahead of both branches, and the loop breaks after either has determined the size. With the usual single-endpoint UVC altsetting nothing changes, which is why this stayed unnoticed; it matters when a streaming altsetting also exposes a still-image endpoint. ___ Differential Revision: D115344628 fbshipit-source-id: 41b3ec4272c51f2322bec198b86325f3b8c56d82
1 parent 2c5ecf0 commit 7c00af4

1 file changed

Lines changed: 16 additions & 11 deletions

File tree

impl/ocean/system/usb/Device.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,13 @@ int Device::determineIsochronousTransferLayout(libusb_context* usbContext, const
549549
{
550550
const libusb_endpoint_descriptor& endpointDescriptor = altSetting.endpoint[endpointIndex];
551551

552+
// a SuperSpeed altsetting can expose several endpoints and each of them carries a companion descriptor, so the address has to be checked for both variants below
553+
554+
if (endpointDescriptor.bEndpointAddress != endpointAddress)
555+
{
556+
continue;
557+
}
558+
552559
libusb_ss_endpoint_companion_descriptor* endpointCompanionDescriptor = nullptr;
553560
if (libusb_get_ss_endpoint_companion_descriptor(usbContext, &endpointDescriptor, &endpointCompanionDescriptor) == LIBUSB_SUCCESS)
554561
{
@@ -559,22 +566,20 @@ int Device::determineIsochronousTransferLayout(libusb_context* usbContext, const
559566
}
560567
else
561568
{
562-
if (endpointDescriptor.bEndpointAddress == endpointAddress)
563-
{
564-
const uint16_t wMaxPacketSize = endpointDescriptor.wMaxPacketSize;
565-
ocean_assert((wMaxPacketSize & 0xE000u) == 0u); // the upper 3 bits should always be zero, otherwise we may have USB 3.0
569+
const uint16_t wMaxPacketSize = endpointDescriptor.wMaxPacketSize;
570+
ocean_assert((wMaxPacketSize & 0xE000u) == 0u); // the upper 3 bits should always be zero, otherwise we may have USB 3.0
566571

567-
const uint16_t sizePerTransaction = wMaxPacketSize & 0x7FFu; // the lower 11 bits provide the actual size of the transaction
572+
const uint16_t sizePerTransaction = wMaxPacketSize & 0x7FFu; // the lower 11 bits provide the actual size of the transaction
568573

569-
const uint16_t additionalTransactions = (wMaxPacketSize >> 11u) & 0b11u; // the next two bytes give the number of additional transactions
570-
ocean_assert(additionalTransactions <= 2u);
574+
const uint16_t additionalTransactions = (wMaxPacketSize >> 11u) & 0b11u; // the next two bytes give the number of additional transactions
575+
ocean_assert(additionalTransactions <= 2u);
571576

572-
const uint16_t overallTransactions = additionalTransactions + 1u;
577+
const uint16_t overallTransactions = additionalTransactions + 1u;
573578

574-
endpointPacketSize = uint32_t(sizePerTransaction) * uint32_t(overallTransactions);
575-
break;
576-
}
579+
endpointPacketSize = uint32_t(sizePerTransaction) * uint32_t(overallTransactions);
577580
}
581+
582+
break;
578583
}
579584

580585
if (endpointPacketSize >= maxPayloadTransferSize)

0 commit comments

Comments
 (0)