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
|
||||
};
|
||||
|
||||
EnsureCapacityAligned((nuint)buffer.Length);
|
||||
|
||||
var ioHdr = new SgIoHdrT();
|
||||
|
||||
ioHdr.interface_id = 'S';
|
||||
@@ -71,13 +73,14 @@ partial class Device
|
||||
ioHdr.mx_sb_len = (byte)SenseBuffer.Length;
|
||||
ioHdr.dxfer_direction = dir;
|
||||
ioHdr.dxfer_len = (uint)buffer.Length;
|
||||
ioHdr.dxferp = Marshal.AllocHGlobal(buffer.Length);
|
||||
ioHdr.dxferp = (IntPtr)_nativeBuffer;
|
||||
ioHdr.cmdp = (IntPtr)CdbPtr;
|
||||
ioHdr.sbp = (IntPtr)SensePtr;
|
||||
ioHdr.timeout = timeout * 1000;
|
||||
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();
|
||||
cmdStopWatch.Start();
|
||||
@@ -86,14 +89,13 @@ partial class Device
|
||||
|
||||
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;
|
||||
|
||||
duration = ioHdr.duration > 0 ? ioHdr.duration : cmdStopWatch.Elapsed.TotalMilliseconds;
|
||||
|
||||
Marshal.FreeHGlobal(ioHdr.dxferp);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
using Aaru.CommonTypes.Enums;
|
||||
using Aaru.CommonTypes.Interop;
|
||||
@@ -47,14 +48,42 @@ namespace Aaru.Devices.Linux;
|
||||
|
||||
/// <inheritdoc />
|
||||
[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>
|
||||
/// <value>The file handle</value>
|
||||
int _fileDescriptor;
|
||||
|
||||
// Persistent, aligned native buffer
|
||||
private nuint _nativeBuffer;
|
||||
|
||||
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)
|
||||
{
|
||||
errno = ErrorNumber.NoError;
|
||||
|
||||
@@ -44,8 +44,8 @@ namespace Aaru.Devices.Windows;
|
||||
partial class Device
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override int SendScsiCommand(Span<byte> cdb, ref byte[] buffer, uint timeout, ScsiDirection direction,
|
||||
out double duration, out bool sense)
|
||||
public override unsafe int SendScsiCommand(Span<byte> cdb, ref byte[] buffer, uint timeout, ScsiDirection direction,
|
||||
out double duration, out bool sense)
|
||||
{
|
||||
// We need a timeout
|
||||
if(timeout == 0) timeout = Timeout > 0 ? Timeout : 15;
|
||||
@@ -62,6 +62,8 @@ partial class Device
|
||||
_ => ScsiIoctlDirection.Unspecified
|
||||
};
|
||||
|
||||
EnsureCapacityAligned((nuint)buffer.Length);
|
||||
|
||||
var sptdSb = new ScsiPassThroughDirectAndSenseBuffer
|
||||
{
|
||||
SenseBuf = new byte[32],
|
||||
@@ -73,7 +75,7 @@ partial class Device
|
||||
DataIn = dir,
|
||||
DataTransferLength = (uint)buffer.Length,
|
||||
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);
|
||||
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;
|
||||
int error = 0;
|
||||
|
||||
Marshal.Copy(buffer, 0, sptdSb.sptd.DataBuffer, buffer.Length);
|
||||
|
||||
var cmdStopwatch = new Stopwatch();
|
||||
cmdStopwatch.Start();
|
||||
|
||||
@@ -102,7 +105,7 @@ partial class Device
|
||||
|
||||
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;
|
||||
|
||||
@@ -110,8 +113,6 @@ partial class Device
|
||||
|
||||
duration = cmdStopwatch.Elapsed.TotalMilliseconds;
|
||||
|
||||
Marshal.FreeHGlobal(sptdSb.sptd.DataBuffer);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,14 +43,40 @@ namespace Aaru.Devices.Windows;
|
||||
|
||||
/// <inheritdoc />
|
||||
[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>
|
||||
/// <value>The file handle</value>
|
||||
SafeFileHandle _fileHandle;
|
||||
private nuint _nativeBuffer;
|
||||
|
||||
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)
|
||||
{
|
||||
errno = ErrorNumber.NoError;
|
||||
@@ -102,10 +128,10 @@ partial class Device : Devices.Device
|
||||
};
|
||||
|
||||
IntPtr descriptorPtr = Marshal.AllocHGlobal(1000);
|
||||
var descriptorB = new byte[1000];
|
||||
byte[] descriptorB = new byte[1000];
|
||||
|
||||
uint returned = 0;
|
||||
var error = 0;
|
||||
int error = 0;
|
||||
|
||||
bool hasError = !Extern.DeviceIoControlStorageQuery(dev._fileHandle,
|
||||
WindowsIoctl.IoctlStorageQueryProperty,
|
||||
@@ -203,7 +229,7 @@ partial class Device : Devices.Device
|
||||
|
||||
if(IsSdhci(dev._fileHandle))
|
||||
{
|
||||
var sdBuffer = new byte[16];
|
||||
byte[] sdBuffer = new byte[16];
|
||||
|
||||
dev.LastError = dev.SendMmcCommand(MmcCommands.SendCsd,
|
||||
false,
|
||||
|
||||
Reference in New Issue
Block a user