From b62bb24fe4f2a2829bb584f7c1e5c687f7eae2f1 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sat, 30 Jan 2016 14:01:29 +0100 Subject: [PATCH] USB: Force spec mandated control pipe max packet sizes. While the USB descriptors are specifically built in such a way that it's always possible to correctly query the max packet size, some devices unfortunatley use bogus values in their descriptors and rely on the stack to use the mandated values. This fixes USB devices in VirtualBox when EHCI emulation is used. This really is a bug in their descriptor emulation though. --- src/add-ons/kernel/bus_managers/usb/Pipe.cpp | 29 +++++++++++++++++++ .../kernel/bus_managers/usb/usb_private.h | 8 +++++ 2 files changed, 37 insertions(+) diff --git a/src/add-ons/kernel/bus_managers/usb/Pipe.cpp b/src/add-ons/kernel/bus_managers/usb/Pipe.cpp index f3170285e6..96525ac359 100644 --- a/src/add-ons/kernel/bus_managers/usb/Pipe.cpp +++ b/src/add-ons/kernel/bus_managers/usb/Pipe.cpp @@ -328,6 +328,35 @@ ControlPipe::~ControlPipe() } +void +ControlPipe::InitCommon(int8 deviceAddress, uint8 endpointAddress, + usb_speed speed, pipeDirection direction, size_t maxPacketSize, + uint8 interval, int8 hubAddress, uint8 hubPort) +{ + // The USB 2.0 spec section 5.5.3 gives fixed max packet sizes for the + // different speeds. The USB 3.1 specs defines the max packet size to a + // fixed 512 for control endpoints in 9.6.6. Some devices ignore these + // values and use bogus ones, so we restrict them here. + switch (speed) { + case USB_SPEED_LOWSPEED: + maxPacketSize = 8; + break; + case USB_SPEED_HIGHSPEED: + maxPacketSize = 64; + break; + case USB_SPEED_SUPER: + maxPacketSize = 512; + break; + + default: + break; + } + + Pipe::InitCommon(deviceAddress, endpointAddress, speed, direction, + maxPacketSize, interval, hubAddress, hubPort); +} + + status_t ControlPipe::SendRequest(uint8 requestType, uint8 request, uint16 value, uint16 index, uint16 length, void *data, size_t dataLength, diff --git a/src/add-ons/kernel/bus_managers/usb/usb_private.h b/src/add-ons/kernel/bus_managers/usb/usb_private.h index 2e20979e88..49f7e18157 100644 --- a/src/add-ons/kernel/bus_managers/usb/usb_private.h +++ b/src/add-ons/kernel/bus_managers/usb/usb_private.h @@ -355,6 +355,14 @@ public: ControlPipe(Object *parent); virtual ~ControlPipe(); +virtual void InitCommon(int8 deviceAddress, + uint8 endpointAddress, + usb_speed speed, + pipeDirection direction, + size_t maxPacketSize, + uint8 interval, + int8 hubAddress, uint8 hubPort); + virtual uint32 Type() const { return USB_OBJECT_PIPE | USB_OBJECT_CONTROL_PIPE; } virtual const char * TypeName() const