From bd5174de49486c5d5f1f22acc5796cc070fd8485 Mon Sep 17 00:00:00 2001 From: TREFOU Felix Date: Fri, 2 Jun 2023 14:06:12 +0200 Subject: [PATCH 1/3] Allow device to separatelly attach/detach interface from kernel driver --- src/main/java/org/usb4java/javax/AbstractDevice.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/usb4java/javax/AbstractDevice.java b/src/main/java/org/usb4java/javax/AbstractDevice.java index 39da623..53b244f 100644 --- a/src/main/java/org/usb4java/javax/AbstractDevice.java +++ b/src/main/java/org/usb4java/javax/AbstractDevice.java @@ -74,6 +74,9 @@ abstract class AbstractDevice implements UsbDevice /** The numbers of the currently claimed interface. */ private Set claimedInterfaceNumbers = new HashSet(); + /** The numbers of the currently kernel claimed interface. */ + private Set claimedKernelInterfaceNumbers = new HashSet(); + /** The port this device is connected to. */ private UsbPort port; @@ -81,9 +84,6 @@ abstract class AbstractDevice implements UsbDevice private final ControlIrpQueue queue = new ControlIrpQueue(this, this.listeners); - /** If kernel driver was detached when interface was claimed. */ - private boolean detachedKernelDriver; - /** * Constructs a new device. * @@ -420,7 +420,7 @@ final void claimInterface(final byte number, final boolean force) throw ExceptionUtils.createPlatformException( "Unable to detach kernel driver", result); } - this.detachedKernelDriver = true; + claimedKernelInterfaceNumbers.add(number); } } @@ -456,7 +456,7 @@ final void releaseInterface(final byte number) throws UsbException "Unable to release interface", result); } - if (this.detachedKernelDriver) + if (this.claimedKernelInterfaceNumbers.contains(number)) { result = LibUsb.attachKernelDriver(handle, number & 0xff); if (result < 0) @@ -464,6 +464,7 @@ final void releaseInterface(final byte number) throws UsbException throw ExceptionUtils.createPlatformException( "Unable to re-attach kernel driver", result); } + this.claimedKernelInterfaceNumbers.remove(number); } this.claimedInterfaceNumbers.remove(number); From a6f0daef74a3ade65fe75c404b134aa0abef49db Mon Sep 17 00:00:00 2001 From: TREFOU Felix Date: Fri, 2 Jun 2023 14:07:21 +0200 Subject: [PATCH 2/3] Fixed USBDevice read locked after interfaces attach/detach --- .../org/usb4java/javax/AbstractDevice.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/main/java/org/usb4java/javax/AbstractDevice.java b/src/main/java/org/usb4java/javax/AbstractDevice.java index 53b244f..2d80522 100644 --- a/src/main/java/org/usb4java/javax/AbstractDevice.java +++ b/src/main/java/org/usb4java/javax/AbstractDevice.java @@ -248,6 +248,14 @@ public final void close() } } + public final void reset() + { + if (this.handle != null) + { + LibUsb.resetDevice(this.handle); + } + } + @Override public final UsbPort getParentUsbPort() { @@ -400,6 +408,12 @@ final void setActiveUsbConfigurationNumber(final byte number) final void claimInterface(final byte number, final boolean force) throws UsbException { + if(this.claimedInterfaceNumbers.isEmpty()) { + // This prevent a libus bug where async read could lock + // forever after a full released interfaces + reset(); + } + if (this.claimedInterfaceNumbers.contains(number)) throw new UsbClaimException("An interface is already claimed"); @@ -468,6 +482,12 @@ final void releaseInterface(final byte number) throws UsbException } this.claimedInterfaceNumbers.remove(number); + + if(this.claimedInterfaceNumbers.isEmpty()) { + // This prevent a libus bug where async read could lock + // forever after a full released interfaces + reset(); + } } /** From 5c554cc72216f58fbfa30c7f8bbabf7875303565 Mon Sep 17 00:00:00 2001 From: TREFOU Felix Date: Thu, 17 Aug 2023 00:45:35 +0200 Subject: [PATCH 3/3] Handled usb bulk out transferts of wMaxPacketSize multiple --- src/main/java/org/usb4java/javax/IrpQueue.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/org/usb4java/javax/IrpQueue.java b/src/main/java/org/usb4java/javax/IrpQueue.java index ec1a04b..810baf0 100644 --- a/src/main/java/org/usb4java/javax/IrpQueue.java +++ b/src/main/java/org/usb4java/javax/IrpQueue.java @@ -167,6 +167,17 @@ private int write(final byte[] data, final int offset, final int len) // Short packet detected, aborting if (result < size) break; } + + // Handle bulk out transfert needing zlp to detect end of packet + if ((this.pipe.getUsbEndpoint().getDirection() == UsbConst.ENDPOINT_DIRECTION_OUT)) { + if (type == LibUsb.TRANSFER_TYPE_BULK) { + if ((len > 0) && (len % descriptor.wMaxPacketSize() == 0)) { + transfer(handle, descriptor, type, ByteBuffer.allocateDirect(0)); + } + } + } + + return written; }