2020-07-19 22:01:25 +01:00
|
|
|
// /***************************************************************************
|
|
|
|
|
// Aaru Data Preservation Suite
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
|
//
|
|
|
|
|
// Filename : ErrorLog.cs
|
|
|
|
|
// Author(s) : Natalia Portillo <claunia@claunia.com>
|
|
|
|
|
//
|
|
|
|
|
// Component : Core algorithms.
|
|
|
|
|
//
|
|
|
|
|
// --[ 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 <http://www.gnu.org/licenses/>.
|
|
|
|
|
//
|
|
|
|
|
// ----------------------------------------------------------------------------
|
2022-02-18 10:02:53 +00:00
|
|
|
// Copyright © 2011-2022 Natalia Portillo
|
2020-07-19 22:01:25 +01:00
|
|
|
// ****************************************************************************/
|
|
|
|
|
|
2020-07-13 18:54:41 +01:00
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using Aaru.Decoders.ATA;
|
|
|
|
|
using Aaru.Decoders.SCSI;
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
namespace Aaru.Core.Logging;
|
|
|
|
|
|
|
|
|
|
/// <summary>Logs errors</summary>
|
|
|
|
|
public sealed class ErrorLog
|
2020-07-13 18:54:41 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
readonly StreamWriter _logSw;
|
|
|
|
|
|
|
|
|
|
/// <summary>Initializes the error log</summary>
|
|
|
|
|
/// <param name="outputFile">Output log file</param>
|
|
|
|
|
public ErrorLog(string outputFile)
|
2020-07-13 18:54:41 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
if(string.IsNullOrEmpty(outputFile))
|
|
|
|
|
return;
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
_logSw = new StreamWriter(outputFile, true);
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
_logSw.WriteLine("Start error logging at {0}", DateTime.Now);
|
|
|
|
|
_logSw.WriteLine("######################################################");
|
|
|
|
|
_logSw.Flush();
|
|
|
|
|
}
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
/// <summary>Finishes and closes the error log</summary>
|
|
|
|
|
public void Close()
|
|
|
|
|
{
|
|
|
|
|
_logSw.WriteLine("######################################################");
|
|
|
|
|
_logSw.WriteLine("End logging at {0}", DateTime.Now);
|
|
|
|
|
_logSw.Close();
|
|
|
|
|
}
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
/// <summary>Register an ATA error after sending a CHS command</summary>
|
|
|
|
|
/// <param name="command">Command</param>
|
|
|
|
|
/// <param name="osError"><c>true</c> if operating system returned an error status instead of the device</param>
|
|
|
|
|
/// <param name="errno">Operating system error number</param>
|
|
|
|
|
/// <param name="registers">Error registers</param>
|
|
|
|
|
public void WriteLine(string command, bool osError, int errno, AtaErrorRegistersChs registers)
|
|
|
|
|
{
|
|
|
|
|
if(osError)
|
2020-07-13 18:54:41 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
_logSw.WriteLine("ATA command {0} operating system error: {1}.", command, errno);
|
|
|
|
|
_logSw.Flush();
|
2020-07-13 18:54:41 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
else
|
2020-07-13 18:54:41 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
List<string> error = new List<string>();
|
|
|
|
|
List<string> status = new List<string>();
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x01) == 0x01)
|
|
|
|
|
status.Add("ERR");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x02) == 0x02)
|
|
|
|
|
status.Add("IDX");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x04) == 0x04)
|
|
|
|
|
status.Add("CORR");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x08) == 0x08)
|
|
|
|
|
status.Add("DRQ");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x10) == 0x10)
|
|
|
|
|
status.Add("SRV");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x20) == 0x20)
|
|
|
|
|
status.Add("DF");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x40) == 0x40)
|
|
|
|
|
status.Add("RDY");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x80) == 0x80)
|
|
|
|
|
status.Add("BSY");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x01) == 0x01)
|
|
|
|
|
error.Add("AMNF");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x02) == 0x02)
|
|
|
|
|
error.Add("T0NF");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x04) == 0x04)
|
|
|
|
|
error.Add("ABRT");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x08) == 0x08)
|
|
|
|
|
error.Add("MCR");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x10) == 0x10)
|
|
|
|
|
error.Add("IDNF");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x20) == 0x20)
|
|
|
|
|
error.Add("MC");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x40) == 0x40)
|
|
|
|
|
error.Add("UNC");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x80) == 0x80)
|
|
|
|
|
error.Add("BBK");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
_logSw.WriteLine("ATA command {0} error: status = {1}, error = {2}.", command, string.Join(' ', status),
|
|
|
|
|
string.Join(' ', error));
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
_logSw.Flush();
|
2020-07-13 18:54:41 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
/// <summary>Register an ATA error after trying to read using CHS commands</summary>
|
|
|
|
|
/// <param name="cylinder">Cylinder</param>
|
|
|
|
|
/// <param name="head">Head</param>
|
|
|
|
|
/// <param name="sector">Sector</param>
|
|
|
|
|
/// <param name="osError"><c>true</c> if operating system returned an error status instead of the device</param>
|
|
|
|
|
/// <param name="errno">Operating system error number</param>
|
|
|
|
|
/// <param name="registers">Error registers</param>
|
|
|
|
|
public void WriteLine(ushort cylinder, byte head, byte sector, bool osError, int errno,
|
|
|
|
|
AtaErrorRegistersChs registers)
|
|
|
|
|
{
|
|
|
|
|
if(osError)
|
2020-07-13 18:54:41 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
_logSw.WriteLine("ATA reading C/H/S {0}/{1}/{2} operating system error: {3}.", cylinder, head, sector,
|
|
|
|
|
errno);
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
_logSw.Flush();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
List<string> error = new List<string>();
|
|
|
|
|
List<string> status = new List<string>();
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x01) == 0x01)
|
|
|
|
|
status.Add("ERR");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x02) == 0x02)
|
|
|
|
|
status.Add("IDX");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x04) == 0x04)
|
|
|
|
|
status.Add("CORR");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x08) == 0x08)
|
|
|
|
|
status.Add("DRQ");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x10) == 0x10)
|
|
|
|
|
status.Add("SRV");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x20) == 0x20)
|
|
|
|
|
status.Add("DF");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x40) == 0x40)
|
|
|
|
|
status.Add("RDY");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x80) == 0x80)
|
|
|
|
|
status.Add("BSY");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x01) == 0x01)
|
|
|
|
|
error.Add("AMNF");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x02) == 0x02)
|
|
|
|
|
error.Add("T0NF");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x04) == 0x04)
|
|
|
|
|
error.Add("ABRT");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x08) == 0x08)
|
|
|
|
|
error.Add("MCR");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x10) == 0x10)
|
|
|
|
|
error.Add("IDNF");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x20) == 0x20)
|
|
|
|
|
error.Add("MC");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x40) == 0x40)
|
|
|
|
|
error.Add("UNC");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x80) == 0x80)
|
|
|
|
|
error.Add("BBK");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
_logSw.WriteLine("ATA reading C/H/S {0}/{1}/{2} error: status = {3}, error = {4}.", cylinder, head,
|
|
|
|
|
sector, string.Join(' ', status), string.Join(' ', error));
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
_logSw.Flush();
|
2020-07-13 18:54:41 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
/// <summary>Register an ATA error after trying to read using 28-bit LBA commands</summary>
|
|
|
|
|
/// <param name="block">Starting block</param>
|
|
|
|
|
/// <param name="osError"><c>true</c> if operating system returned an error status instead of the device</param>
|
|
|
|
|
/// <param name="errno">Operating system error number</param>
|
|
|
|
|
/// <param name="registers">Error registers</param>
|
|
|
|
|
public void WriteLine(ulong block, bool osError, int errno, AtaErrorRegistersLba28 registers)
|
|
|
|
|
{
|
|
|
|
|
if(osError)
|
2020-07-13 18:54:41 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
_logSw.WriteLine("ATA reading LBA {0} operating system error: {1}.", block, errno);
|
|
|
|
|
_logSw.Flush();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
List<string> error = new List<string>();
|
|
|
|
|
List<string> status = new List<string>();
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x01) == 0x01)
|
|
|
|
|
status.Add("ERR");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x02) == 0x02)
|
|
|
|
|
status.Add("IDX");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x04) == 0x04)
|
|
|
|
|
status.Add("CORR");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x08) == 0x08)
|
|
|
|
|
status.Add("DRQ");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x10) == 0x10)
|
|
|
|
|
status.Add("SRV");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x20) == 0x20)
|
|
|
|
|
status.Add("DF");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x40) == 0x40)
|
|
|
|
|
status.Add("RDY");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x80) == 0x80)
|
|
|
|
|
status.Add("BSY");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x01) == 0x01)
|
|
|
|
|
error.Add("AMNF");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x02) == 0x02)
|
|
|
|
|
error.Add("T0NF");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x04) == 0x04)
|
|
|
|
|
error.Add("ABRT");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x08) == 0x08)
|
|
|
|
|
error.Add("MCR");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x10) == 0x10)
|
|
|
|
|
error.Add("IDNF");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x20) == 0x20)
|
|
|
|
|
error.Add("MC");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x40) == 0x40)
|
|
|
|
|
error.Add("UNC");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x80) == 0x80)
|
|
|
|
|
error.Add("BBK");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
_logSw.WriteLine("ATA reading LBA {0} error: status = {1}, error = {2}.", block,
|
|
|
|
|
string.Join(' ', status), string.Join(' ', error));
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
_logSw.Flush();
|
2020-07-13 18:54:41 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
/// <summary>Register an ATA error after trying to read using 48-bit LBA commands</summary>
|
|
|
|
|
/// <param name="block">Starting block</param>
|
|
|
|
|
/// <param name="osError"><c>true</c> if operating system returned an error status instead of the device</param>
|
|
|
|
|
/// <param name="errno">Operating system error number</param>
|
|
|
|
|
/// <param name="registers">Error registers</param>
|
|
|
|
|
public void WriteLine(ulong block, bool osError, int errno, AtaErrorRegistersLba48 registers)
|
|
|
|
|
{
|
|
|
|
|
if(osError)
|
2020-07-13 18:54:41 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
_logSw.WriteLine("ATA reading LBA {0} operating system error: {1}.", block, errno);
|
|
|
|
|
_logSw.Flush();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
List<string> error = new List<string>();
|
|
|
|
|
List<string> status = new List<string>();
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x01) == 0x01)
|
|
|
|
|
status.Add("ERR");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x02) == 0x02)
|
|
|
|
|
status.Add("IDX");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x04) == 0x04)
|
|
|
|
|
status.Add("CORR");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x08) == 0x08)
|
|
|
|
|
status.Add("DRQ");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x10) == 0x10)
|
|
|
|
|
status.Add("SRV");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x20) == 0x20)
|
|
|
|
|
status.Add("DF");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x40) == 0x40)
|
|
|
|
|
status.Add("RDY");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Status & 0x80) == 0x80)
|
|
|
|
|
status.Add("BSY");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x01) == 0x01)
|
|
|
|
|
error.Add("AMNF");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x02) == 0x02)
|
|
|
|
|
error.Add("T0NF");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x04) == 0x04)
|
|
|
|
|
error.Add("ABRT");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x08) == 0x08)
|
|
|
|
|
error.Add("MCR");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x10) == 0x10)
|
|
|
|
|
error.Add("IDNF");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x20) == 0x20)
|
|
|
|
|
error.Add("MC");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x40) == 0x40)
|
|
|
|
|
error.Add("UNC");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if((registers.Error & 0x80) == 0x80)
|
|
|
|
|
error.Add("BBK");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
_logSw.WriteLine("ATA reading LBA {0} error: status = {1}, error = {2}.", block,
|
|
|
|
|
string.Join(' ', status), string.Join(' ', error));
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
_logSw.Flush();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>Register a SCSI error after sending a command</summary>
|
|
|
|
|
/// <param name="command">Command</param>
|
|
|
|
|
/// <param name="osError"><c>true</c> if operating system returned an error status instead of the device</param>
|
|
|
|
|
/// <param name="errno">Operating system error number</param>
|
|
|
|
|
/// <param name="senseBuffer">REQUEST SENSE response buffer</param>
|
|
|
|
|
public void WriteLine(string command, bool osError, int errno, byte[] senseBuffer)
|
|
|
|
|
{
|
|
|
|
|
if(osError)
|
|
|
|
|
{
|
|
|
|
|
_logSw.WriteLine("SCSI command {0} operating system error: {1}.", command, errno);
|
|
|
|
|
_logSw.Flush();
|
|
|
|
|
|
|
|
|
|
return;
|
2020-07-13 18:54:41 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
DecodedSense? decodedSense = Sense.Decode(senseBuffer);
|
|
|
|
|
string prettySense = Sense.PrettifySense(senseBuffer);
|
|
|
|
|
string hexSense = string.Join(' ', senseBuffer.Select(b => $"{b:X2}"));
|
|
|
|
|
|
|
|
|
|
if(decodedSense.HasValue)
|
2020-07-13 18:54:41 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
if(prettySense != null)
|
2020-07-13 18:54:41 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
if(prettySense.StartsWith("SCSI SENSE: ", StringComparison.Ordinal))
|
|
|
|
|
prettySense = prettySense.Substring(12);
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(prettySense.EndsWith('\n'))
|
|
|
|
|
prettySense = prettySense.Substring(0, prettySense.Length - 1);
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
prettySense = prettySense.Replace("\n", " - ");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
_logSw.WriteLine("SCSI command {0} error: SENSE {1} ASC {2:X2}h ASCQ {3:X2}h, {4}, {5}.", command,
|
|
|
|
|
decodedSense.Value.SenseKey, decodedSense.Value.ASC, decodedSense.Value.ASCQ,
|
|
|
|
|
hexSense, prettySense);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_logSw.WriteLine("SCSI command {0} error: SENSE {1} ASC {2:X2}h ASCQ {3:X2}h, {4}.", command,
|
|
|
|
|
decodedSense.Value.SenseKey, decodedSense.Value.ASC, decodedSense.Value.ASCQ,
|
|
|
|
|
hexSense);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if(prettySense != null)
|
2020-07-13 18:54:41 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
if(prettySense.StartsWith("SCSI SENSE: ", StringComparison.Ordinal))
|
|
|
|
|
prettySense = prettySense.Substring(12);
|
|
|
|
|
|
|
|
|
|
if(prettySense.EndsWith('\n'))
|
|
|
|
|
prettySense = prettySense.Substring(0, prettySense.Length - 1);
|
|
|
|
|
|
|
|
|
|
prettySense = prettySense.Replace("\n", " - ");
|
|
|
|
|
|
|
|
|
|
_logSw.WriteLine("SCSI command {0} error: {1}, {2}.", command, hexSense, prettySense);
|
2020-07-13 18:54:41 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
_logSw.WriteLine("SCSI command {0} error: {1}", command, hexSense);
|
2020-07-13 18:54:41 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
_logSw.Flush();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>Register an SCSI error after trying to read</summary>
|
|
|
|
|
/// <param name="block">Starting block</param>
|
|
|
|
|
/// <param name="osError"><c>true</c> if operating system returned an error status instead of the device</param>
|
|
|
|
|
/// <param name="errno">Operating system error number</param>
|
|
|
|
|
/// <param name="senseBuffer">REQUEST SENSE response buffer</param>
|
|
|
|
|
public void WriteLine(ulong block, bool osError, int errno, byte[] senseBuffer)
|
|
|
|
|
{
|
|
|
|
|
if(osError)
|
|
|
|
|
{
|
|
|
|
|
_logSw.WriteLine("SCSI reading LBA {0} operating system error: {1}.", block, errno);
|
2020-07-13 18:54:41 +01:00
|
|
|
_logSw.Flush();
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
if(senseBuffer is null ||
|
|
|
|
|
senseBuffer.Length == 0 ||
|
|
|
|
|
senseBuffer.All(s => s == 0))
|
|
|
|
|
return;
|
2020-07-13 18:54:41 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
DecodedSense? decodedSense = Sense.Decode(senseBuffer);
|
|
|
|
|
string prettySense = Sense.PrettifySense(senseBuffer);
|
|
|
|
|
string hexSense = string.Join(' ', senseBuffer.Select(b => $"{b:X2}"));
|
|
|
|
|
|
|
|
|
|
if(decodedSense.HasValue)
|
2020-07-13 18:54:41 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
if(prettySense != null)
|
2020-07-13 18:54:41 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
if(prettySense.StartsWith("SCSI SENSE: ", StringComparison.Ordinal))
|
|
|
|
|
prettySense = prettySense.Substring(12);
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(prettySense.EndsWith('\n'))
|
|
|
|
|
prettySense = prettySense.Substring(0, prettySense.Length - 1);
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
prettySense = prettySense.Replace("\n", " - ");
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
_logSw.WriteLine("SCSI reading LBA {0} error: SENSE {1} ASC {2:X2}h ASCQ {3:X2}h, {4}, {5}.", block,
|
|
|
|
|
decodedSense.Value.SenseKey, decodedSense.Value.ASC, decodedSense.Value.ASCQ,
|
|
|
|
|
hexSense, prettySense);
|
2020-07-13 18:54:41 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
_logSw.WriteLine("SCSI reading LBA {0} error: SENSE {1} ASC {2:X2}h ASCQ {3:X2}h, {4}.", block,
|
|
|
|
|
decodedSense.Value.SenseKey, decodedSense.Value.ASC, decodedSense.Value.ASCQ,
|
|
|
|
|
hexSense);
|
2020-07-13 18:54:41 +01:00
|
|
|
}
|
|
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
else
|
2020-07-13 18:54:41 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
if(prettySense != null)
|
2020-07-13 18:54:41 +01:00
|
|
|
{
|
2022-03-06 13:29:38 +00:00
|
|
|
if(prettySense.StartsWith("SCSI SENSE: ", StringComparison.Ordinal))
|
|
|
|
|
prettySense = prettySense.Substring(12);
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
if(prettySense.EndsWith('\n'))
|
|
|
|
|
prettySense = prettySense.Substring(0, prettySense.Length - 1);
|
|
|
|
|
|
|
|
|
|
prettySense = prettySense.Replace("\n", " - ");
|
|
|
|
|
|
|
|
|
|
_logSw.WriteLine("SCSI reading LBA {0} error: {1}, {2}.", block, hexSense, prettySense);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
_logSw.WriteLine("SCSI reading LBA {0} error: {1}", block, hexSense);
|
2020-07-13 18:54:41 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
}
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
_logSw.Flush();
|
|
|
|
|
}
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
/// <summary>Register a SecureDigital / MultiMediaCard error after sending a command</summary>
|
|
|
|
|
/// <param name="command">Command</param>
|
|
|
|
|
/// <param name="osError"><c>true</c> if operating system returned an error status instead of the device</param>
|
|
|
|
|
/// <param name="errno">Operating system error number</param>
|
|
|
|
|
/// <param name="response">Response</param>
|
|
|
|
|
public void WriteLine(string command, bool osError, int errno, uint[] response)
|
|
|
|
|
{
|
|
|
|
|
if(osError)
|
|
|
|
|
{
|
|
|
|
|
_logSw.WriteLine("SD/MMC command {0} operating system error: {1}.", command, errno);
|
2020-07-13 18:54:41 +01:00
|
|
|
_logSw.Flush();
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
return;
|
2020-07-13 18:54:41 +01:00
|
|
|
}
|
|
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
// TODO: Decode response
|
|
|
|
|
_logSw.WriteLine("SD/MMC command {0} error: {1}", command,
|
|
|
|
|
string.Join(" - ", response.Select(r => $"0x{r:X8}")));
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
_logSw.Flush();
|
|
|
|
|
}
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
/// <summary>Register a SecureDigital / MultiMediaCard error after trying to read</summary>
|
|
|
|
|
/// <param name="block">Starting block</param>
|
|
|
|
|
/// <param name="osError"><c>true</c> if operating system returned an error status instead of the device</param>
|
|
|
|
|
/// <param name="errno">Operating system error number</param>
|
|
|
|
|
/// <param name="byteAddressed">Byte addressed</param>
|
|
|
|
|
/// <param name="response">Response</param>
|
|
|
|
|
public void WriteLine(ulong block, bool osError, int errno, bool byteAddressed, uint[] response)
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
{
|
|
|
|
|
if(osError)
|
|
|
|
|
{
|
|
|
|
|
_logSw.WriteLine("SD/MMC reading LBA {0} ({1}-addressed) operating system error: {2}.", block,
|
|
|
|
|
byteAddressed ? "byte" : "block", errno);
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
_logSw.Flush();
|
2020-07-13 18:54:41 +01:00
|
|
|
|
2022-03-06 13:29:38 +00:00
|
|
|
return;
|
2020-07-13 18:54:41 +01:00
|
|
|
}
|
2022-03-06 13:29:38 +00:00
|
|
|
|
|
|
|
|
_logSw.WriteLine("SD/MMC reading LBA {0} ({1}-addressed) error: {2}", block,
|
|
|
|
|
byteAddressed ? "byte" : "block", string.Join(" - ", response.Select(r => $"0x{r:X8}")));
|
|
|
|
|
|
|
|
|
|
throw new NotImplementedException();
|
2020-07-13 18:54:41 +01:00
|
|
|
}
|
|
|
|
|
}
|