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
|
/// <c>True</c> if SCSI error returned non-OK status and <paramref name="senseBuffer" /> contains SCSI
|
||||||
/// sense
|
/// sense
|
||||||
/// </param>
|
/// </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)
|
ScsiIoctlDirection direction, out double duration, out bool sense)
|
||||||
{
|
{
|
||||||
senseBuffer = null;
|
senseBuffer = null;
|
||||||
@@ -78,6 +79,7 @@ namespace DiscImageChef.Devices.Linux
|
|||||||
ioHdr.cmdp = Marshal.AllocHGlobal(cdb.Length);
|
ioHdr.cmdp = Marshal.AllocHGlobal(cdb.Length);
|
||||||
ioHdr.sbp = Marshal.AllocHGlobal(senseBuffer.Length);
|
ioHdr.sbp = Marshal.AllocHGlobal(senseBuffer.Length);
|
||||||
ioHdr.timeout = timeout * 1000;
|
ioHdr.timeout = timeout * 1000;
|
||||||
|
ioHdr.flags = (uint)SgFlags.DirectIo;
|
||||||
|
|
||||||
Marshal.Copy(buffer, 0, ioHdr.dxferp, buffer.Length);
|
Marshal.Copy(buffer, 0, ioHdr.dxferp, buffer.Length);
|
||||||
Marshal.Copy(cdb, 0, ioHdr.cmdp, cdb.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="protocol">ATA protocol to use</param>
|
||||||
/// <param name="transferRegister">Which register contains the transfer count</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>
|
/// <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,
|
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)
|
out bool sense)
|
||||||
{
|
{
|
||||||
duration = 0;
|
duration = 0;
|
||||||
@@ -183,7 +187,8 @@ namespace DiscImageChef.Devices.Linux
|
|||||||
cdb[13] = registers.DeviceHead;
|
cdb[13] = registers.DeviceHead;
|
||||||
cdb[14] = registers.Command;
|
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);
|
AtaProtocolToScsiDirection(protocol), out duration, out sense);
|
||||||
|
|
||||||
if(senseBuffer.Length < 22 || senseBuffer[8] != 0x09 && senseBuffer[9] != 0x0C) return error;
|
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>
|
/// <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,
|
internal static int SendAtaCommand(int fd, AtaRegistersLba28 registers,
|
||||||
out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol,
|
out AtaErrorRegistersLba28 errorRegisters, AtaProtocol protocol,
|
||||||
AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout,
|
AtaTransferRegister transferRegister, ref byte[] buffer,
|
||||||
bool transferBlocks, out double duration, out bool sense)
|
uint timeout,
|
||||||
|
bool transferBlocks, out double duration,
|
||||||
|
out bool sense)
|
||||||
{
|
{
|
||||||
duration = 0;
|
duration = 0;
|
||||||
sense = false;
|
sense = false;
|
||||||
@@ -258,7 +265,8 @@ namespace DiscImageChef.Devices.Linux
|
|||||||
cdb[13] = registers.DeviceHead;
|
cdb[13] = registers.DeviceHead;
|
||||||
cdb[14] = registers.Command;
|
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);
|
AtaProtocolToScsiDirection(protocol), out duration, out sense);
|
||||||
|
|
||||||
if(senseBuffer.Length < 22 || senseBuffer[8] != 0x09 && senseBuffer[9] != 0x0C) return error;
|
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>
|
/// <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,
|
internal static int SendAtaCommand(int fd, AtaRegistersLba48 registers,
|
||||||
out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol,
|
out AtaErrorRegistersLba48 errorRegisters, AtaProtocol protocol,
|
||||||
AtaTransferRegister transferRegister, ref byte[] buffer, uint timeout,
|
AtaTransferRegister transferRegister, ref byte[] buffer,
|
||||||
bool transferBlocks, out double duration, out bool sense)
|
uint timeout,
|
||||||
|
bool transferBlocks, out double duration,
|
||||||
|
out bool sense)
|
||||||
{
|
{
|
||||||
duration = 0;
|
duration = 0;
|
||||||
sense = false;
|
sense = false;
|
||||||
@@ -339,7 +349,8 @@ namespace DiscImageChef.Devices.Linux
|
|||||||
cdb[13] = registers.DeviceHead;
|
cdb[13] = registers.DeviceHead;
|
||||||
cdb[14] = registers.Command;
|
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);
|
AtaProtocolToScsiDirection(protocol), out duration, out sense);
|
||||||
|
|
||||||
if(senseBuffer.Length < 22 || senseBuffer[8] != 0x09 && senseBuffer[9] != 0x0C) return error;
|
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="argument">Command argument</param>
|
||||||
/// <param name="response">Response registers</param>
|
/// <param name="response">Response registers</param>
|
||||||
/// <param name="blockSize">Size of block in bytes</param>
|
/// <param name="blockSize">Size of block in bytes</param>
|
||||||
internal static int SendMmcCommand(int fd, MmcCommands command, bool write, bool isApplication, MmcFlags flags,
|
internal static int SendMmcCommand(int fd, MmcCommands command, bool write,
|
||||||
uint argument, uint blockSize, uint blocks, ref byte[] buffer,
|
bool isApplication, MmcFlags flags,
|
||||||
out uint[] response, out double duration, out bool sense, uint timeout = 0)
|
uint argument, uint blockSize, uint blocks,
|
||||||
|
ref byte[] buffer,
|
||||||
|
out uint[] response, out double duration, out bool sense,
|
||||||
|
uint timeout = 0)
|
||||||
{
|
{
|
||||||
response = null;
|
response = null;
|
||||||
duration = 0;
|
duration = 0;
|
||||||
@@ -403,6 +417,7 @@ namespace DiscImageChef.Devices.Linux
|
|||||||
ioCmd.data_timeout_ns = timeout * 1000000000;
|
ioCmd.data_timeout_ns = timeout * 1000000000;
|
||||||
ioCmd.cmd_timeout_ms = timeout * 1000;
|
ioCmd.cmd_timeout_ms = timeout * 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
ioCmd.data_ptr = (ulong)bufPtr;
|
ioCmd.data_ptr = (ulong)bufPtr;
|
||||||
|
|
||||||
Marshal.Copy(buffer, 0, bufPtr, buffer.Length);
|
Marshal.Copy(buffer, 0, bufPtr, buffer.Length);
|
||||||
|
|||||||
Reference in New Issue
Block a user