mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Use a single device aligned buffer.
This commit is contained in:
@@ -64,6 +64,8 @@ partial class Device
|
|||||||
_ => ScsiIoctlDirection.Unknown
|
_ => ScsiIoctlDirection.Unknown
|
||||||
};
|
};
|
||||||
|
|
||||||
|
EnsureCapacityAligned((nuint)buffer.Length);
|
||||||
|
|
||||||
var ioHdr = new SgIoHdrT();
|
var ioHdr = new SgIoHdrT();
|
||||||
|
|
||||||
ioHdr.interface_id = 'S';
|
ioHdr.interface_id = 'S';
|
||||||
@@ -71,13 +73,14 @@ partial class Device
|
|||||||
ioHdr.mx_sb_len = (byte)SenseBuffer.Length;
|
ioHdr.mx_sb_len = (byte)SenseBuffer.Length;
|
||||||
ioHdr.dxfer_direction = dir;
|
ioHdr.dxfer_direction = dir;
|
||||||
ioHdr.dxfer_len = (uint)buffer.Length;
|
ioHdr.dxfer_len = (uint)buffer.Length;
|
||||||
ioHdr.dxferp = Marshal.AllocHGlobal(buffer.Length);
|
ioHdr.dxferp = (IntPtr)_nativeBuffer;
|
||||||
ioHdr.cmdp = (IntPtr)CdbPtr;
|
ioHdr.cmdp = (IntPtr)CdbPtr;
|
||||||
ioHdr.sbp = (IntPtr)SensePtr;
|
ioHdr.sbp = (IntPtr)SensePtr;
|
||||||
ioHdr.timeout = timeout * 1000;
|
ioHdr.timeout = timeout * 1000;
|
||||||
ioHdr.flags = (uint)SgFlags.DirectIo;
|
ioHdr.flags = (uint)SgFlags.DirectIo;
|
||||||
|
|
||||||
Marshal.Copy(buffer, 0, ioHdr.dxferp, buffer.Length);
|
// OUT or bidirectional → pre‑fill from managed buffer
|
||||||
|
if(direction != ScsiDirection.In) buffer.AsSpan().CopyTo(new Span<byte>((void*)_nativeBuffer, buffer.Length));
|
||||||
|
|
||||||
var cmdStopWatch = new Stopwatch();
|
var cmdStopWatch = new Stopwatch();
|
||||||
cmdStopWatch.Start();
|
cmdStopWatch.Start();
|
||||||
@@ -86,14 +89,13 @@ partial class Device
|
|||||||
|
|
||||||
if(error < 0) error = Marshal.GetLastWin32Error();
|
if(error < 0) error = Marshal.GetLastWin32Error();
|
||||||
|
|
||||||
Marshal.Copy(ioHdr.dxferp, buffer, 0, buffer.Length);
|
// IN or bidirectional → copy back into managed buffer
|
||||||
|
if(direction != ScsiDirection.Out) new Span<byte>((void*)_nativeBuffer, buffer.Length).CopyTo(buffer);
|
||||||
|
|
||||||
sense |= (ioHdr.info & SgInfo.OkMask) != SgInfo.Ok;
|
sense |= (ioHdr.info & SgInfo.OkMask) != SgInfo.Ok;
|
||||||
|
|
||||||
duration = ioHdr.duration > 0 ? ioHdr.duration : cmdStopWatch.Elapsed.TotalMilliseconds;
|
duration = ioHdr.duration > 0 ? ioHdr.duration : cmdStopWatch.Elapsed.TotalMilliseconds;
|
||||||
|
|
||||||
Marshal.FreeHGlobal(ioHdr.dxferp);
|
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
using Aaru.CommonTypes.Enums;
|
using Aaru.CommonTypes.Enums;
|
||||||
using Aaru.CommonTypes.Interop;
|
using Aaru.CommonTypes.Interop;
|
||||||
@@ -47,14 +48,42 @@ namespace Aaru.Devices.Linux;
|
|||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[SupportedOSPlatform("linux")]
|
[SupportedOSPlatform("linux")]
|
||||||
partial class Device : Devices.Device
|
partial class Device : Devices.Device, IDisposable
|
||||||
{
|
{
|
||||||
|
private const nuint ALIGNMENT = 64;
|
||||||
|
private nuint _capacity;
|
||||||
/// <summary>Gets the file handle representing this device</summary>
|
/// <summary>Gets the file handle representing this device</summary>
|
||||||
/// <value>The file handle</value>
|
/// <value>The file handle</value>
|
||||||
int _fileDescriptor;
|
int _fileDescriptor;
|
||||||
|
|
||||||
|
// Persistent, aligned native buffer
|
||||||
|
private nuint _nativeBuffer;
|
||||||
|
|
||||||
Device() {}
|
Device() {}
|
||||||
|
|
||||||
|
#region IDisposable Members
|
||||||
|
|
||||||
|
public new unsafe void Dispose()
|
||||||
|
{
|
||||||
|
if(_nativeBuffer == 0) return;
|
||||||
|
NativeMemory.AlignedFree((void*)_nativeBuffer);
|
||||||
|
_nativeBuffer = 0;
|
||||||
|
_capacity = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
private unsafe void EnsureCapacityAligned(nuint size)
|
||||||
|
{
|
||||||
|
if(size <= _capacity) return;
|
||||||
|
|
||||||
|
if(_nativeBuffer != 0) NativeMemory.AlignedFree((void*)_nativeBuffer);
|
||||||
|
|
||||||
|
_nativeBuffer = (nuint)NativeMemory.AlignedAlloc(size, ALIGNMENT);
|
||||||
|
_capacity = size;
|
||||||
|
}
|
||||||
|
|
||||||
internal new static Device Create(string devicePath, out ErrorNumber errno)
|
internal new static Device Create(string devicePath, out ErrorNumber errno)
|
||||||
{
|
{
|
||||||
errno = ErrorNumber.NoError;
|
errno = ErrorNumber.NoError;
|
||||||
|
|||||||
@@ -44,8 +44,8 @@ namespace Aaru.Devices.Windows;
|
|||||||
partial class Device
|
partial class Device
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public override int SendScsiCommand(Span<byte> cdb, ref byte[] buffer, uint timeout, ScsiDirection direction,
|
public override unsafe int SendScsiCommand(Span<byte> cdb, ref byte[] buffer, uint timeout, ScsiDirection direction,
|
||||||
out double duration, out bool sense)
|
out double duration, out bool sense)
|
||||||
{
|
{
|
||||||
// We need a timeout
|
// We need a timeout
|
||||||
if(timeout == 0) timeout = Timeout > 0 ? Timeout : 15;
|
if(timeout == 0) timeout = Timeout > 0 ? Timeout : 15;
|
||||||
@@ -62,6 +62,8 @@ partial class Device
|
|||||||
_ => ScsiIoctlDirection.Unspecified
|
_ => ScsiIoctlDirection.Unspecified
|
||||||
};
|
};
|
||||||
|
|
||||||
|
EnsureCapacityAligned((nuint)buffer.Length);
|
||||||
|
|
||||||
var sptdSb = new ScsiPassThroughDirectAndSenseBuffer
|
var sptdSb = new ScsiPassThroughDirectAndSenseBuffer
|
||||||
{
|
{
|
||||||
SenseBuf = new byte[32],
|
SenseBuf = new byte[32],
|
||||||
@@ -73,7 +75,7 @@ partial class Device
|
|||||||
DataIn = dir,
|
DataIn = dir,
|
||||||
DataTransferLength = (uint)buffer.Length,
|
DataTransferLength = (uint)buffer.Length,
|
||||||
TimeOutValue = timeout,
|
TimeOutValue = timeout,
|
||||||
DataBuffer = Marshal.AllocHGlobal(buffer.Length)
|
DataBuffer = (IntPtr)_nativeBuffer
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -81,11 +83,12 @@ partial class Device
|
|||||||
sptdSb.sptd.SenseInfoOffset = (uint)Marshal.SizeOf(sptdSb.sptd);
|
sptdSb.sptd.SenseInfoOffset = (uint)Marshal.SizeOf(sptdSb.sptd);
|
||||||
cdb.CopyTo(sptdSb.sptd.Cdb);
|
cdb.CopyTo(sptdSb.sptd.Cdb);
|
||||||
|
|
||||||
|
// OUT or BiDir → pre‑copy
|
||||||
|
if(direction != ScsiDirection.In) buffer.AsSpan().CopyTo(new Span<byte>((void*)_nativeBuffer, buffer.Length));
|
||||||
|
|
||||||
uint k = 0;
|
uint k = 0;
|
||||||
int error = 0;
|
int error = 0;
|
||||||
|
|
||||||
Marshal.Copy(buffer, 0, sptdSb.sptd.DataBuffer, buffer.Length);
|
|
||||||
|
|
||||||
var cmdStopwatch = new Stopwatch();
|
var cmdStopwatch = new Stopwatch();
|
||||||
cmdStopwatch.Start();
|
cmdStopwatch.Start();
|
||||||
|
|
||||||
@@ -102,7 +105,7 @@ partial class Device
|
|||||||
|
|
||||||
if(hasError) error = Marshal.GetLastWin32Error();
|
if(hasError) error = Marshal.GetLastWin32Error();
|
||||||
|
|
||||||
Marshal.Copy(sptdSb.sptd.DataBuffer, buffer, 0, buffer.Length);
|
if(direction != ScsiDirection.Out) new Span<byte>((void*)_nativeBuffer, buffer.Length).CopyTo(buffer);
|
||||||
|
|
||||||
sense |= sptdSb.sptd.ScsiStatus != 0;
|
sense |= sptdSb.sptd.ScsiStatus != 0;
|
||||||
|
|
||||||
@@ -110,8 +113,6 @@ partial class Device
|
|||||||
|
|
||||||
duration = cmdStopwatch.Elapsed.TotalMilliseconds;
|
duration = cmdStopwatch.Elapsed.TotalMilliseconds;
|
||||||
|
|
||||||
Marshal.FreeHGlobal(sptdSb.sptd.DataBuffer);
|
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,14 +43,40 @@ namespace Aaru.Devices.Windows;
|
|||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
[SupportedOSPlatform("windows")]
|
[SupportedOSPlatform("windows")]
|
||||||
partial class Device : Devices.Device
|
partial class Device : Devices.Device, IDisposable
|
||||||
{
|
{
|
||||||
|
private const nuint ALIGNMENT = 64;
|
||||||
|
private nuint _capacity;
|
||||||
/// <summary>Gets the file handle representing this device</summary>
|
/// <summary>Gets the file handle representing this device</summary>
|
||||||
/// <value>The file handle</value>
|
/// <value>The file handle</value>
|
||||||
SafeFileHandle _fileHandle;
|
SafeFileHandle _fileHandle;
|
||||||
|
private nuint _nativeBuffer;
|
||||||
|
|
||||||
Device() {}
|
Device() {}
|
||||||
|
|
||||||
|
#region IDisposable Members
|
||||||
|
|
||||||
|
public new unsafe void Dispose()
|
||||||
|
{
|
||||||
|
if(_nativeBuffer == 0) return;
|
||||||
|
NativeMemory.AlignedFree((void*)_nativeBuffer);
|
||||||
|
_nativeBuffer = 0;
|
||||||
|
_capacity = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private unsafe void EnsureCapacityAligned(nuint size)
|
||||||
|
{
|
||||||
|
if(size <= _capacity) return;
|
||||||
|
|
||||||
|
if(_nativeBuffer != 0) NativeMemory.AlignedFree((void*)_nativeBuffer);
|
||||||
|
|
||||||
|
_nativeBuffer = (nuint)NativeMemory.AlignedAlloc(size, ALIGNMENT);
|
||||||
|
|
||||||
|
_capacity = size;
|
||||||
|
}
|
||||||
|
|
||||||
internal new static Device Create(string devicePath, out ErrorNumber errno)
|
internal new static Device Create(string devicePath, out ErrorNumber errno)
|
||||||
{
|
{
|
||||||
errno = ErrorNumber.NoError;
|
errno = ErrorNumber.NoError;
|
||||||
@@ -102,10 +128,10 @@ partial class Device : Devices.Device
|
|||||||
};
|
};
|
||||||
|
|
||||||
IntPtr descriptorPtr = Marshal.AllocHGlobal(1000);
|
IntPtr descriptorPtr = Marshal.AllocHGlobal(1000);
|
||||||
var descriptorB = new byte[1000];
|
byte[] descriptorB = new byte[1000];
|
||||||
|
|
||||||
uint returned = 0;
|
uint returned = 0;
|
||||||
var error = 0;
|
int error = 0;
|
||||||
|
|
||||||
bool hasError = !Extern.DeviceIoControlStorageQuery(dev._fileHandle,
|
bool hasError = !Extern.DeviceIoControlStorageQuery(dev._fileHandle,
|
||||||
WindowsIoctl.IoctlStorageQueryProperty,
|
WindowsIoctl.IoctlStorageQueryProperty,
|
||||||
@@ -203,7 +229,7 @@ partial class Device : Devices.Device
|
|||||||
|
|
||||||
if(IsSdhci(dev._fileHandle))
|
if(IsSdhci(dev._fileHandle))
|
||||||
{
|
{
|
||||||
var sdBuffer = new byte[16];
|
byte[] sdBuffer = new byte[16];
|
||||||
|
|
||||||
dev.LastError = dev.SendMmcCommand(MmcCommands.SendCsd,
|
dev.LastError = dev.SendMmcCommand(MmcCommands.SendCsd,
|
||||||
false,
|
false,
|
||||||
|
|||||||
Reference in New Issue
Block a user