Commit e1cf30a1 authored by Ben Avison's avatar Ben Avison
Browse files

Fix inability to recover from disc errors 08 and 21

  These disc errors relate to the status of the task file registers before
  a command is issued, however with SATA (unlike PATA) we can't simply read
  the task file on demand, we need to issue a command to cause a register FIS
  transaction to happen on the bus. The only available command which is
  compatible with all device types (packet and non-packet) and which can be
  issued in not-ready state is EXECUTE_DEVICE_DIAGNOSTIC, so issue this when
  either disc error is encountered and retry to give the drive a chance to
  return to ready/not-busy state. This command has the advantage of having
  been mandatory back to ATA-1 so should be harmless for PATA drives, whether
  connected via a PATA-SATA bridge or via a future PATADriver module.
  Tested on Titanium.

Version 4.02. Tagged as 'ADFS-4_02'
parent 86c19b05
/* (4.01)
/* (4.02)
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
#define Module_MajorVersion_CMHG 4.01
#define Module_MajorVersion_CMHG 4.02
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 13 Mar 2016
#define Module_Date_CMHG 24 Mar 2016
#define Module_MajorVersion "4.01"
#define Module_Version 401
#define Module_MajorVersion "4.02"
#define Module_Version 402
#define Module_MinorVersion ""
#define Module_Date "13 Mar 2016"
#define Module_Date "24 Mar 2016"
#define Module_ApplicationDate "13-Mar-16"
#define Module_ApplicationDate "24-Mar-16"
#define Module_ComponentName "ADFS"
#define Module_ComponentPath "cddl/RiscOS/Sources/FileSys/ADFS/ADFS"
#define Module_FullVersion "4.01"
#define Module_HelpVersion "4.01 (13 Mar 2016)"
#define Module_LibraryVersionInfo "4:1"
#define Module_FullVersion "4.02"
#define Module_HelpVersion "4.02 (24 Mar 2016)"
#define Module_LibraryVersionInfo "4:2"
......@@ -169,6 +169,26 @@ static low_level_error_t transfer_with_retries(uint32_t reason,
e.oserror = MESSAGE_ERRORLOOKUP(true, ExtEscape, 0);
break; /* No retries for this one */
else if (e.oserror && (e.oserror->errnum == ErrorNumber_ATA_CmdBusy ||
e.oserror->errnum == ErrorNumber_ATA_CmdNotRdy))
/* With SATA, we need to kick the device to send us updated task file
* registers to enable us to recover from these error conditions. For
* this, we need a command with no side effects that is valid to issue
* when DRDY is not set; the only candidate valid for all types and
* generations of device is EXECUTE_DEVICE_DIAGNOSTIC. Throw away any
* errors returned from the kick command. */
ataop_param_lba28_t kick_p = {
.device = DEVICE_MAGIC,
uint32_t kick_flags = ATAOp_NoDRDY |
(dr->deviceid << ATAOp_DeviceIDShift) |
(dr->cpid << ATAOp_CPIDShift) |
ATAOp_TransNone |
(flags & ATAOp_DisableEscape);
ata_op_fg_nodata(kick_flags, 7, &kick_p, OP_TIMEOUT);
if (e.oserror && transferred)
++retries; /* At least some data transferred, so it's not fair to decrement the retry count when we loop */
......@@ -131,6 +131,7 @@ enum
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment