mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
On Linux use direct SG_IO.
This commit is contained in:
@@ -56,7 +56,8 @@ namespace DiscImageChef.Devices.Linux
|
||||
/// <c>True</c> if SCSI error returned non-OK status and <paramref name="senseBuffer" /> contains SCSI
|
||||
/// sense
|
||||
/// </param>
|
||||
internal static int SendScsiCommand(int fd, byte[] cdb, ref byte[] buffer, out byte[] senseBuffer, uint timeout,
|
||||
internal static int SendScsiCommand(int fd, byte[] cdb, ref byte[] buffer,
|
||||
out byte[] senseBuffer, uint timeout,
|
||||
ScsiIoctlDirection direction, out double duration, out bool sense)
|
||||
{
|
||||
senseBuffer = null;
|
||||
@@ -78,6 +79,7 @@ namespace DiscImageChef.Devices.Linux
|
||||
ioHdr.cmdp = Marshal.AllocHGlobal(cdb.Length);
|
||||
ioHdr.sbp = Marshal.AllocHGlobal(senseBuffer.Length);
|
||||
ioHdr.timeout = timeout * 1000;
|
||||
ioHdr.flags = (uint)SgFlags.DirectIo;
|
||||
|
||||
Marshal.Copy(buffer, 0, ioHdr.dxferp, buffer.Length);
|
||||
Marshal.Copy(cdb, 0, ioHdr.cmdp, cdb.Length);
|
||||
@@ -141,9 +143,11 @@ namespace DiscImageChef.Devices.Linux
|
||||
/// <param name="protocol">ATA protocol to use</param>
|
||||
/// <param name="transferRegister">Which register contains the transfer count</param>
|
||||
/// <param name="transferBlocks">Set to <c>true</c> if the transfer count is in blocks, otherwise it is in bytes</param>
|
||||
internal static int SendAtaCommand(int fd, AtaRegistersChs registers, out AtaErrorRegistersChs errorRegisters,
|
||||
internal static int SendAtaCommand(int fd, AtaRegistersChs registers,
|
||||
out AtaErrorRegistersChs errorRegisters,
|
||||
AtaProtocol protocol, AtaTransferRegister transferRegister,
|
||||
ref byte[] buffer, uint timeout, bool transferBlocks, out double duration,
|
||||
ref byte[] buffer, uint timeout, bool transferBlocks,
|
||||
out double duration,
|
||||
out bool sense)
|
||||
{
|
||||
duration = 0;
|
||||
@@ -183,7 +187,8 @@ namespace DiscImageChef.Devices.Linux
|
||||
cdb[13] = registers.DeviceHead;
|
||||
cdb[14] = registers.Command;
|
||||
|
||||
int error = SendScsiCommand(fd, cdb, ref buffer, out byte[] senseBuffer, timeout,
|
||||
int error = SendScsiCommand(fd, cdb, ref buffer,
|
||||
out byte[] senseBuffer, timeout,
|
||||
AtaProtocolToScsiDirection(protocol), out duration, out sense);
|
||||
|
||||
if(senseBuffer.Length < 22 || senseBuffer[8] != 0x09 && senseBuffer[9] != 0x0C) return error;
|
||||
@@ -218,8 +223,10 @@ namespace DiscImageChef.Devices.Linux
|
||||
/// <param name="transferBlocks">Set to <c>true</c> if the transfer count is in blocks, otherwise it is in bytes</param>
|
||||
internal static int SendAtaCommand(int fd, AtaRegistersLba28 registers,
|
||||
out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol,
|
||||
AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout,
|
||||
bool transferBlocks, out double duration, out bool sense)
|
||||
AtaTransferRegister transferRegister, ref byte[] buffer,
|
||||
uint timeout,
|
||||
bool transferBlocks, out double duration,
|
||||
out bool sense)
|
||||
{
|
||||
duration = 0;
|
||||
sense = false;
|
||||
@@ -258,7 +265,8 @@ namespace DiscImageChef.Devices.Linux
|
||||
cdb[13] = registers.DeviceHead;
|
||||
cdb[14] = registers.Command;
|
||||
|
||||
int error = SendScsiCommand(fd, cdb, ref buffer, out byte[] senseBuffer, timeout,
|
||||
int error = SendScsiCommand(fd, cdb, ref buffer,
|
||||
out byte[] senseBuffer, timeout,
|
||||
AtaProtocolToScsiDirection(protocol), out duration, out sense);
|
||||
|
||||
if(senseBuffer.Length < 22 || senseBuffer[8] != 0x09 && senseBuffer[9] != 0x0C) return error;
|
||||
@@ -293,8 +301,10 @@ namespace DiscImageChef.Devices.Linux
|
||||
/// <param name="transferBlocks">Set to <c>true</c> if the transfer count is in blocks, otherwise it is in bytes</param>
|
||||
internal static int SendAtaCommand(int fd, AtaRegistersLba48 registers,
|
||||
out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol,
|
||||
AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout,
|
||||
bool transferBlocks, out double duration, out bool sense)
|
||||
AtaTransferRegister transferRegister, ref byte[] buffer,
|
||||
uint timeout,
|
||||
bool transferBlocks, out double duration,
|
||||
out bool sense)
|
||||
{
|
||||
duration = 0;
|
||||
sense = false;
|
||||
@@ -339,7 +349,8 @@ namespace DiscImageChef.Devices.Linux
|
||||
cdb[13] = registers.DeviceHead;
|
||||
cdb[14] = registers.Command;
|
||||
|
||||
int error = SendScsiCommand(fd, cdb, ref buffer, out byte[] senseBuffer, timeout,
|
||||
int error = SendScsiCommand(fd, cdb, ref buffer,
|
||||
out byte[] senseBuffer, timeout,
|
||||
AtaProtocolToScsiDirection(protocol), out duration, out sense);
|
||||
|
||||
if(senseBuffer.Length < 22 || senseBuffer[8] != 0x09 && senseBuffer[9] != 0x0C) return error;
|
||||
@@ -377,9 +388,12 @@ namespace DiscImageChef.Devices.Linux
|
||||
/// <param name="argument">Command argument</param>
|
||||
/// <param name="response">Response registers</param>
|
||||
/// <param name="blockSize">Size of block in bytes</param>
|
||||
internal static int SendMmcCommand(int fd, MmcCommands command, bool write, bool isApplication, MmcFlags flags,
|
||||
uint argument, uint blockSize, uint blocks, ref byte[] buffer,
|
||||
out uint[] response, out double duration, out bool sense, uint timeout = 0)
|
||||
internal static int SendMmcCommand(int fd, MmcCommands command, bool write,
|
||||
bool isApplication, MmcFlags flags,
|
||||
uint argument, uint blockSize, uint blocks,
|
||||
ref byte[] buffer,
|
||||
out uint[] response, out double duration, out bool sense,
|
||||
uint timeout = 0)
|
||||
{
|
||||
response = null;
|
||||
duration = 0;
|
||||
@@ -403,6 +417,7 @@ namespace DiscImageChef.Devices.Linux
|
||||
ioCmd.data_timeout_ns = timeout * 1000000000;
|
||||
ioCmd.cmd_timeout_ms = timeout * 1000;
|
||||
}
|
||||
|
||||
ioCmd.data_ptr = (ulong)bufPtr;
|
||||
|
||||
Marshal.Copy(buffer, 0, bufPtr, buffer.Length);
|
||||
|
||||
Reference in New Issue
Block a user