diff --git a/DiscImageChef.Devices/ChangeLog b/DiscImageChef.Devices/ChangeLog index 5cbb4e3eb..8f656a52b 100644 --- a/DiscImageChef.Devices/ChangeLog +++ b/DiscImageChef.Devices/ChangeLog @@ -1,3 +1,10 @@ +2016-01-13 Natalia Portillo + + * Enums.cs: + * DiscImageChef.Devices.csproj: + * Device/ScsiCommands/Adaptec.cs: + Added Adaptec ACB-4000A and ACB-4070 vendor commands. + 2016-01-13 Natalia Portillo * Device/ScsiCommands/SMC.cs: diff --git a/DiscImageChef.Devices/Device/ScsiCommands/Adaptec.cs b/DiscImageChef.Devices/Device/ScsiCommands/Adaptec.cs new file mode 100644 index 000000000..d45f71ffb --- /dev/null +++ b/DiscImageChef.Devices/Device/ScsiCommands/Adaptec.cs @@ -0,0 +1,226 @@ +// /*************************************************************************** +// The Disc Image Chef +// ---------------------------------------------------------------------------- +// +// Filename : Adaptec.cs +// Version : 1.0 +// Author(s) : Natalia Portillo +// +// Component : Adaptec vendor commands +// +// Revision : $Revision$ +// Last change by : $Author$ +// Date : $Date$ +// +// --[ Description ] ---------------------------------------------------------- +// +// Commands described for Adaptec ACB-4000A and ACB-4070 ST-506 to SCSI controllers +// +// --[ License ] -------------------------------------------------------------- +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// ---------------------------------------------------------------------------- +// Copyright (C) 2011-2015 Claunia.com +// ****************************************************************************/ +// //$Id$ +using System; +using DiscImageChef.Console; + +namespace DiscImageChef.Devices +{ + public partial class Device + { + /// + /// Gets the underlying drive cylinder, head and index bytes for the specified SCSI LBA. + /// + /// Buffer. + /// Sense buffer. + /// SCSI. + /// Timeout. + /// Duration. + public bool AdaptecTranslate(out byte[] buffer, out byte[] senseBuffer, uint lba, uint timeout, out double duration) + { + return AdaptecTranslate(out buffer, out senseBuffer, false, lba, timeout, out duration); + } + + /// + /// Gets the underlying drive cylinder, head and index bytes for the specified SCSI LBA. + /// + /// Buffer. + /// Sense buffer. + /// If set to true request the data from drive 1. + /// SCSI. + /// Timeout. + /// Duration. + public bool AdaptecTranslate(out byte[] buffer, out byte[] senseBuffer, bool drive1, uint lba, uint timeout, out double duration) + { + buffer = new byte[8]; + byte[] cdb = new byte[6]; + senseBuffer = new byte[32]; + bool sense; + + cdb[0] = (byte)ScsiCommands.Adaptec_Translate; + cdb[1] = (byte)((lba & 0x1F0000) >> 16); + cdb[2] = (byte)((lba & 0xFF00) >> 8); + cdb[3] = (byte)(lba & 0xFF); + if (drive1) + cdb[1] += 0x20; + + lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense); + error = lastError != 0; + + DicConsole.DebugWriteLine("SCSI Device", "ADAPTEC TRANSLATE took {0} ms.", duration); + + return sense; + } + + /// + /// Sets the error threshold + /// + /// true, if set error threshold was adapteced, false otherwise. + /// Threshold. 0 to disable error reporting. + /// Sense buffer. + /// Timeout. + /// Duration. + public bool AdaptecSetErrorThreshold(byte threshold, out byte[] senseBuffer, uint timeout, out double duration) + { + return AdaptecSetErrorThreshold(threshold, out senseBuffer, false, timeout, out duration); + } + + /// + /// Sets the error threshold + /// + /// true, if set error threshold was adapteced, false otherwise. + /// Threshold. 0 to disable error reporting. + /// Sense buffer. + /// If set to true set the threshold from drive 1. + /// Timeout. + /// Duration. + public bool AdaptecSetErrorThreshold(byte threshold, out byte[] senseBuffer, bool drive1, uint timeout, out double duration) + { + byte[] buffer = new byte[1]; + buffer[0] = threshold; + byte[] cdb = new byte[6]; + senseBuffer = new byte[32]; + bool sense; + + cdb[0] = (byte)ScsiCommands.Adaptec_SetErrorThreshold; + if (drive1) + cdb[1] += 0x20; + cdb[4] = 1; + + lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.Out, out duration, out sense); + error = lastError != 0; + + DicConsole.DebugWriteLine("SCSI Device", "ADAPTEC SET ERROR THRESHOLD took {0} ms.", duration); + + return sense; + } + + /// + /// Requests the usage, seek and error counters, and resets them + /// + /// Buffer. + /// Sense buffer. + /// Timeout. + /// Duration. + public bool AdaptecReadUsageCounter(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration) + { + return AdaptecReadUsageCounter(out buffer, out senseBuffer, false, timeout, out duration); + } + + /// + /// Requests the usage, seek and error counters, and resets them + /// + /// Buffer. + /// Sense buffer. + /// If set to true get the counters from drive 1. + /// Timeout. + /// Duration. + public bool AdaptecReadUsageCounter(out byte[] buffer, out byte[] senseBuffer, bool drive1, uint timeout, out double duration) + { + buffer = new byte[9]; + byte[] cdb = new byte[6]; + senseBuffer = new byte[32]; + bool sense; + + cdb[0] = (byte)ScsiCommands.Adaptec_Translate; + if (drive1) + cdb[1] += 0x20; + cdb[4] = (byte)buffer.Length; + + lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense); + error = lastError != 0; + + DicConsole.DebugWriteLine("SCSI Device", "ADAPTEC READ/RESET USAGE COUNTER took {0} ms.", duration); + + return sense; + } + + /// + /// Fills the Adaptec controller RAM with 1K bytes of data + /// + /// Data to fill the buffer with. + /// Sense buffer. + /// Timeout. + /// Duration. + public bool AdaptecWriteBuffer(byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration) + { + byte[] oneKBuffer = new byte[1024]; + if (buffer.Length < 1024) + Array.Copy(buffer, 0, oneKBuffer, 0, buffer.Length); + else + Array.Copy(buffer, 0, oneKBuffer, 0, 1024); + + byte[] cdb = new byte[6]; + senseBuffer = new byte[32]; + bool sense; + + cdb[0] = (byte)ScsiCommands.Adaptec_WriteBuffer; + + lastError = SendScsiCommand(cdb, ref oneKBuffer, out senseBuffer, timeout, ScsiDirection.Out, out duration, out sense); + error = lastError != 0; + + DicConsole.DebugWriteLine("SCSI Device", "ADAPTEC WRITE DATA BUFFER took {0} ms.", duration); + + return sense; + } + + /// + /// Reads 1K bytes of data from the Adaptec controller RAM + /// + /// Buffer. + /// Sense buffer. + /// Timeout. + /// Duration. + public bool AdaptecReadBuffer(out byte[] buffer, out byte[] senseBuffer, uint timeout, out double duration) + { + buffer = new byte[1024]; + byte[] cdb = new byte[6]; + senseBuffer = new byte[32]; + bool sense; + + cdb[0] = (byte)ScsiCommands.Adaptec_ReadBuffer; + + lastError = SendScsiCommand(cdb, ref buffer, out senseBuffer, timeout, ScsiDirection.In, out duration, out sense); + error = lastError != 0; + + DicConsole.DebugWriteLine("SCSI Device", "ADAPTEC READ DATA BUFFER took {0} ms.", duration); + + return sense; + } + } +} + diff --git a/DiscImageChef.Devices/DiscImageChef.Devices.csproj b/DiscImageChef.Devices/DiscImageChef.Devices.csproj index 484e78011..619af967a 100644 --- a/DiscImageChef.Devices/DiscImageChef.Devices.csproj +++ b/DiscImageChef.Devices/DiscImageChef.Devices.csproj @@ -59,6 +59,7 @@ + diff --git a/DiscImageChef.Devices/Enums.cs b/DiscImageChef.Devices/Enums.cs index ca28c6634..cdaa9374f 100644 --- a/DiscImageChef.Devices/Enums.cs +++ b/DiscImageChef.Devices/Enums.cs @@ -1369,6 +1369,14 @@ namespace DiscImageChef.Devices /// Found on a vendor source code /// ControllerDiagnostic = 0xE4, + /// + /// Found on a vendor document + /// + ReadLong = 0xE5, + /// + /// Found on a vendor document + /// + WriteLong = 0xE6 #endregion SASI Class 7 commands } @@ -2595,8 +2603,16 @@ namespace DiscImageChef.Devices /// /// Reads CD-DA data /// - NEC_ReadCdDa = 0xD4 + NEC_ReadCdDa = 0xD4, #endregion NEC vendor commands + + #region Adaptec vendor commands + Adaptec_Translate = 0x0F, + Adaptec_SetErrorThreshold = 0x10, + Adaptec_ReadCounters = 0x11, + Adaptec_WriteBuffer = 0x13, + Adaptec_ReadBuffer = 0x14 + #endregion Adaptec vendor commands } #endregion SCSI Commands