Skip to content

Commit 79fe100

Browse files
committed
Fix parsing of USB bus file and remove USB reset
1 parent 0ae7cef commit 79fe100

5 files changed

Lines changed: 51 additions & 33 deletions

File tree

TheAirBlow.Thor.Library/Platform/Linux.cs

Lines changed: 46 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ public async Task<List<DeviceInfo>> GetDevices() {
4242
}
4343

4444
private uint _interface;
45+
private uint _alternate;
4546
private uint? _readEndpoint;
4647
private uint? _writeEndpoint;
4748
private int? _deviceFd;
@@ -94,7 +95,7 @@ public void Initialize(string? id, byte[]? direct = null) {
9495
validity = false;
9596
}
9697
_interface = reader.ReadByte();
97-
file.Seek(1, SeekOrigin.Current);
98+
_alternate = reader.ReadByte();
9899
var numEndpoints = (int)reader.ReadByte();
99100
Log.Debug("Number of endpoints: {0}", numEndpoints);
100101
var clss = reader.ReadByte();
@@ -107,9 +108,10 @@ public void Initialize(string? id, byte[]? direct = null) {
107108
Log.Debug("$$ Endpoint index {0} $$", j);
108109
var len = reader.ReadByte();
109110
var type = reader.ReadByte();
110-
if (type == 0x24) {
111+
while (type == 0x24) {
111112
Log.Debug("!! Class-dependant descriptor, skipping (len = {0} - 2)", len);
112-
file.Seek(len - 2, SeekOrigin.Current); continue;
113+
file.Seek(len - 2, SeekOrigin.Current);
114+
len = reader.ReadByte(); type = reader.ReadByte();
113115
}
114116
if (type != 0x05) {
115117
Log.Debug("!! USB_DT_ENDPOINT fail (value = {0:X2})", type);
@@ -140,27 +142,23 @@ public void Initialize(string? id, byte[]? direct = null) {
140142

141143
file.Dispose();
142144
if (!found) throw new InvalidOperationException("Failed to find valid endpoints!");
143-
Log.Debug("Interface: 0x{0:X2}, Read Endpoint: 0x{1:X2}, Write Endpoint: 0x{2:X2}",
144-
_interface, _readEndpoint, _writeEndpoint);
145+
Log.Debug("Interface: 0x{0:X2}, Alternate: 0x{1:X2}, Read Endpoint: 0x{2:X2}, Write Endpoint: 0x{3:X2}",
146+
_interface, _alternate, _readEndpoint, _writeEndpoint);
145147

146148
// Return in case of direct
147149
if (direct != null) return;
148150

149151
// Create a device file handle
150152
if ((_deviceFd = Interop.Open(path, Interop.O_RDWR)) < 0)
151153
Interop.HandleError("Failed to open the device for RW");
152-
153-
// Reset USB device
154-
var zeroRef = 0u;
155-
if (Interop.IoCtl(_deviceFd.Value, Interop.USBDEVFS_RESET, ref zeroRef) < 0)
156-
Interop.HandleError("Failed to reset USB device");
157-
154+
158155
// Detach kernel driver if present
159156
var driver = new Interop.GetDriver {
160157
Interface = (int)_interface
161158
};
162159

163160
if (Interop.IoCtl(_deviceFd.Value, Interop.USBDEVFS_GETDRIVER, ref driver) > 0) {
161+
Log.Debug("Kernel driver detected, detaching it!");
164162
var ioctl = new Interop.UsbIoCtl {
165163
CommandCode = (int)Interop.USBDEVFS_DISCONNECT,
166164
Interface = (int)_interface,
@@ -172,7 +170,7 @@ public void Initialize(string? id, byte[]? direct = null) {
172170

173171
_detached = true;
174172
}
175-
173+
176174
// Claim interface
177175
if (Interop.IoCtl(_deviceFd.Value, Interop.USBDEVFS_CLAIMINTERFACE, ref _interface) < 0)
178176
Interop.HandleError("Failed to claim interface");
@@ -249,26 +247,33 @@ public void ReadZLP() {
249247

250248
public void Dispose() {
251249
// Release the interface
252-
if (_connected && _deviceFd.HasValue)
253-
if (Interop.IoCtl(_deviceFd.Value, Interop.USBDEVFS_RELEASEINTERFACE, ref _interface) < 0)
254-
Interop.HandleError("Failed to release interface");
250+
try {
251+
if (_connected && _deviceFd.HasValue)
252+
if (Interop.IoCtl(_deviceFd.Value, Interop.USBDEVFS_RELEASEINTERFACE, ref _interface) < 0)
253+
Interop.HandleError("Failed to release interface");
254+
} catch { /* Ignored */ }
255255

256256
// Attach the kernel driver back
257-
if (_detached) {
258-
var ioctl = new Interop.UsbIoCtl {
259-
CommandCode = (int)Interop.USBDEVFS_CONNECT,
260-
Interface = (int)_interface,
261-
Data = nint.Zero
262-
};
263-
if (Interop.IoCtl(_deviceFd!.Value, Interop.USBDEVFS_IOCTL, ref ioctl) < 0)
264-
Interop.HandleError("Failed to attach kernel driver");
265-
}
266-
257+
try {
258+
if (_detached) {
259+
var ioctl = new Interop.UsbIoCtl {
260+
CommandCode = (int)Interop.USBDEVFS_CONNECT,
261+
Interface = (int)_interface,
262+
Data = nint.Zero
263+
};
264+
if (Interop.IoCtl(_deviceFd!.Value, Interop.USBDEVFS_IOCTL, ref ioctl) < 0)
265+
Interop.HandleError("Failed to attach kernel driver");
266+
}
267+
} catch { /* Ignored */ }
268+
267269
// Close device file handle
268-
if (_deviceFd.HasValue && Interop.Close(_deviceFd.Value) < 0)
269-
Interop.HandleError("Failed to close device descriptor");
270+
try {
271+
if (_deviceFd.HasValue && Interop.Close(_deviceFd.Value) < 0)
272+
Interop.HandleError("Failed to close device descriptor");
273+
} catch { /* Ignored */ }
270274

271275
_connected = false;
276+
_detached = false;
272277
}
273278

274279
public static unsafe class Interop {
@@ -291,11 +296,12 @@ private static uint _IOR(uint type, uint nr, uint size)
291296
private static uint _IOW(uint type, uint nr, uint size)
292297
=> (1U << _IOC_DIRSHIFT) | (type << _IOC_TYPESHIFT)
293298
| (nr << _IOC_NRSHIFT) | (size << _IOC_SIZESHIFT);
299+
public static uint USBDEVFS_SETINTERFACE = _IOR('U', 4, (uint)sizeof(SetInterface));
300+
public static uint USBDEVFS_GETDRIVER = _IOW('U', 8, (uint)sizeof(GetDriver));
294301
public static uint USBDEVFS_BULK = _IOWR('U', 2, (uint)sizeof(BulkTransfer));
295302
public static uint USBDEVFS_IOCTL = _IOWR('U', 18, (uint)sizeof(UsbIoCtl));
296-
public static uint USBDEVFS_CLAIMINTERFACE = _IOR('U', 15, sizeof(uint));
297303
public static uint USBDEVFS_RELEASEINTERFACE = _IOR('U', 16, sizeof(uint));
298-
public static uint USBDEVFS_GETDRIVER = _IOW('U', 8, (uint)sizeof(GetDriver));
304+
public static uint USBDEVFS_CLAIMINTERFACE = _IOR('U', 15, sizeof(uint));
299305
public static uint USBDEVFS_DISCONNECT = _IO('U', 22);
300306
public static uint USBDEVFS_CONNECT = _IO('U', 23);
301307
public static uint USBDEVFS_RESET = _IO('U', 20);
@@ -306,6 +312,11 @@ public struct BulkTransfer {
306312
public uint Timeout;
307313
public nint Data;
308314
}
315+
316+
public struct SetInterface {
317+
public uint Interface;
318+
public uint Alternate;
319+
}
309320

310321
public struct GetDriver {
311322
public int Interface;
@@ -336,9 +347,15 @@ public static extern int Open([MarshalAs(UnmanagedType.LPStr)]
336347
[DllImport("libc", EntryPoint = "ioctl", SetLastError = true)]
337348
public static extern int IoCtl(int fd, ulong request, ref GetDriver driver);
338349

350+
[DllImport("libc", EntryPoint = "ioctl", SetLastError = true)]
351+
public static extern int IoCtl(int fd, ulong request, ref SetInterface ioctl);
352+
339353
[DllImport("libc", EntryPoint = "ioctl", SetLastError = true)]
340354
public static extern int IoCtl(int fd, ulong request, ref uint iface);
341355

356+
[DllImport("libc", EntryPoint = "ioctl", SetLastError = true)]
357+
public static extern int IoCtl(int fd, ulong request, nint ptr);
358+
342359
[DllImport("libc", EntryPoint = "strerror")]
343360
public static extern nint StrError(int code);
344361

TheAirBlow.Thor.Library/TheAirBlow.Thor.Library.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
77
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
8-
<Version>1.0.3</Version>
8+
<Version>1.0.4</Version>
99
</PropertyGroup>
1010

1111
<ItemGroup>

TheAirBlow.Thor.Shell/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
.MinimumLevel.Information()
1414
.WriteTo.Console()
1515
.CreateLogger();
16-
AnsiConsole.MarkupLine("[green]Welcome to Thor Shell v1.0.3![/]");
16+
AnsiConsole.MarkupLine("[green]Welcome to Thor Shell v1.0.4![/]");
1717
if (!USB.TryGetHandler(out var handler)) {
1818
AnsiConsole.MarkupLine("[red]A USB handler wasn't written for your platform![/]");
1919
AnsiConsole.MarkupLine($"[red]Currently supported platforms: {USB.GetSupported()}.[/]");

TheAirBlow.Thor.Shell/TheAirBlow.Thor.Shell.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<Nullable>enable</Nullable>
88
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
99
<RootNamespace>ThorRewrite.Shell</RootNamespace>
10-
<Version>1.0.3</Version>
10+
<Version>1.0.4</Version>
1111
</PropertyGroup>
1212

1313
<ItemGroup>

Thor.sln.DotSettings.user

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@
22
<s:Boolean x:Key="/Default/UserDictionary/Words/=EMMC/@EntryIndexedValue">True</s:Boolean>
33

44
<s:Boolean x:Key="/Default/UserDictionary/Words/=Movi/@EntryIndexedValue">True</s:Boolean>
5-
<s:Boolean x:Key="/Default/UserDictionary/Words/=tflash/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
5+
<s:Boolean x:Key="/Default/UserDictionary/Words/=tflash/@EntryIndexedValue">True</s:Boolean>
6+
<s:Boolean x:Key="/Default/UserDictionary/Words/=USBDEVFS/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

0 commit comments

Comments
 (0)