Skip to content

Commit bde6fa1

Browse files
committed
Fix speed detection for USB 3.0 SuperSpeed devices
Without proper speed detection, the client may reject devices for invalid EP max packet sizes
1 parent 8bea4f6 commit bde6fa1

File tree

2 files changed

+33
-15
lines changed

2 files changed

+33
-15
lines changed

app/src/main/java/org/cgutman/usbip/server/protocol/UsbIpDevice.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public class UsbIpDevice {
2727
public static final int USB_SPEED_FULL = 2;
2828
public static final int USB_SPEED_HIGH = 3;
2929
public static final int USB_SPEED_VARIABLE = 4;
30+
public static final int USB_SPEED_SUPER = 5;
3031

3132
public static final int BUS_ID_SIZE = 32;
3233
public static final int DEV_PATH_SIZE = 256;

app/src/main/java/org/cgutman/usbip/service/UsbIpService.java

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -192,10 +192,12 @@ public IBinder onBind(Intent intent) {
192192
private final static int FLAG_POSSIBLE_SPEED_LOW = 0x01;
193193
private final static int FLAG_POSSIBLE_SPEED_FULL = 0x02;
194194
private final static int FLAG_POSSIBLE_SPEED_HIGH = 0x04;
195+
private final static int FLAG_POSSIBLE_SPEED_SUPER = 0x08;
195196
private int detectSpeed(UsbDevice dev, UsbDeviceDescriptor devDesc) {
196197
int possibleSpeeds = FLAG_POSSIBLE_SPEED_LOW |
197198
FLAG_POSSIBLE_SPEED_FULL |
198-
FLAG_POSSIBLE_SPEED_HIGH;
199+
FLAG_POSSIBLE_SPEED_HIGH |
200+
FLAG_POSSIBLE_SPEED_SUPER;
199201

200202
for (int i = 0; i < dev.getInterfaceCount(); i++) {
201203
UsbInterface iface = dev.getInterface(i);
@@ -216,6 +218,10 @@ private int detectSpeed(UsbDevice dev, UsbDeviceDescriptor devDesc) {
216218
// High speed devices can't use control transfer sizes smaller than 64 bytes
217219
possibleSpeeds &= ~FLAG_POSSIBLE_SPEED_HIGH;
218220
}
221+
if (endpoint.getMaxPacketSize() < 512) {
222+
// Super speed devices can't use control transfer sizes smaller than 512 bytes
223+
possibleSpeeds &= ~FLAG_POSSIBLE_SPEED_SUPER;
224+
}
219225
}
220226
else if (endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_INT) {
221227
if (endpoint.getMaxPacketSize() > 8) {
@@ -226,23 +232,27 @@ else if (endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_INT) {
226232
// Full speed devices can't use interrupt transfer sizes larger than 64 bytes
227233
possibleSpeeds &= ~FLAG_POSSIBLE_SPEED_FULL;
228234
}
235+
if (endpoint.getMaxPacketSize() > 512) {
236+
// High speed devices can't use interrupt transfer sizes larger than 512 bytes
237+
possibleSpeeds &= ~FLAG_POSSIBLE_SPEED_HIGH;
238+
}
229239
}
230240
else if (endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
231241
// A bulk endpoint alone can accurately distiniguish between
232-
// full and high speed devices
233-
if (endpoint.getMaxPacketSize() == 512) {
234-
// High speed devices can only use 512 byte bulk transfers
235-
possibleSpeeds = FLAG_POSSIBLE_SPEED_HIGH;
236-
}
237-
else {
238-
// Otherwise it must be full speed
239-
possibleSpeeds = FLAG_POSSIBLE_SPEED_FULL;
240-
}
241-
}
242-
else if (endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_ISOC) {
243-
// If the transfer size is 1024, it must be high speed
244-
if (endpoint.getMaxPacketSize() == 1024) {
245-
possibleSpeeds = FLAG_POSSIBLE_SPEED_HIGH;
242+
// full, high, and super speed devices
243+
switch (endpoint.getMaxPacketSize()) {
244+
case 512:
245+
// High speed devices can only use 512 byte bulk transfers
246+
possibleSpeeds = FLAG_POSSIBLE_SPEED_HIGH;
247+
break;
248+
case 1024:
249+
// Super speed devices can only use 1024 byte bulk transfers
250+
possibleSpeeds = FLAG_POSSIBLE_SPEED_SUPER;
251+
break;
252+
default:
253+
// Otherwise it must be full speed
254+
possibleSpeeds = FLAG_POSSIBLE_SPEED_FULL;
255+
break;
246256
}
247257
}
248258
}
@@ -253,6 +263,10 @@ else if (endpoint.getType() == UsbConstants.USB_ENDPOINT_XFER_ISOC) {
253263
// High speed only supported on USB 2.0 or higher
254264
possibleSpeeds &= ~FLAG_POSSIBLE_SPEED_HIGH;
255265
}
266+
if (devDesc.bcdUSB < 0x300) {
267+
// Super speed only supported on USB 3.0 or higher
268+
possibleSpeeds &= ~FLAG_POSSIBLE_SPEED_SUPER;
269+
}
256270
}
257271

258272
// Return the lowest speed that we're compatible with
@@ -268,6 +282,9 @@ else if ((possibleSpeeds & FLAG_POSSIBLE_SPEED_FULL) != 0) {
268282
else if ((possibleSpeeds & FLAG_POSSIBLE_SPEED_HIGH) != 0) {
269283
return UsbIpDevice.USB_SPEED_HIGH;
270284
}
285+
else if ((possibleSpeeds & FLAG_POSSIBLE_SPEED_SUPER) != 0) {
286+
return UsbIpDevice.USB_SPEED_SUPER;
287+
}
271288
else {
272289
// Something went very wrong in speed detection
273290
return UsbIpDevice.USB_SPEED_UNKNOWN;

0 commit comments

Comments
 (0)