Commit 704af3bc authored by Jeffrey Lee's avatar Jeffrey Lee Committed by ROOL
Browse files

Fix "Too complex" errors causing invalid transfer lengths to be used

When ATA_Op reports a "Too complex" error, the truncated transfer length
that it returns isn't guaranteed to be a multiple of the sector size.
Make sure that we apply the appropriate rounding to the value before
retrying the op.

This issue was discovered while testing long descriptor page tables on
4GB IGEPv5, which has the restriction that only the low 2GB of RAM can
be accessed by the SATA controller. The kernel will (via OS_Memory 19)
instruct SATADriver to use a bounce buffer for any parts of a transfer
which access high RAM, but SATADriver only has a limited bounce buffer
size, which will force it to split the transfer with a "Too complex"
error once the buffer is full. If a mix of low & high RAM is being used
for a transfer then this can easily result in SATADriver suggesting a
transfer length which isn't a multiple of the sector size.

For 2GB/short descriptor page tables this situation is much less likely
to occur, since it'd be rare for a transfer to target a non-DMAable
address (would have to be a mix of RAM & IO memory)

Version 4.06. Tagged as 'ADFS4-4_06'
parent 28bf0210
/* (4.05)
/* (4.06)
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
#define Module_MajorVersion_CMHG 4.05
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 26 Jun 2018
#define Module_MajorVersion_CMHG 4.06
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 27 Feb 2021
#define Module_MajorVersion "4.05"
#define Module_Version 405
#define Module_MajorVersion "4.06"
#define Module_Version 406
#define Module_MinorVersion ""
#define Module_Date "26 Jun 2018"
#define Module_Date "27 Feb 2021"
#define Module_ApplicationDate "26-Jun-18"
#define Module_ApplicationDate "27-Feb-21"
#define Module_ComponentName "ADFS"
#define Module_ComponentPath "cddl/RiscOS/Sources/FileSys/ADFS/ADFS"
#define Module_ComponentName "ADFS4"
#define Module_FullVersion "4.05"
#define Module_HelpVersion "4.05 (26 Jun 2018)"
#define Module_LibraryVersionInfo "4:5"
#define Module_FullVersion "4.06"
#define Module_HelpVersion "4.06 (27 Feb 2021)"
#define Module_LibraryVersionInfo "4:6"
......@@ -374,6 +374,17 @@ low_level_error_t discop(uint32_t reason,
e = transfer_with_retries(reason, flags, dr, disc_address, ptr, &remain);
while (e.oserror && e.oserror->errnum == ErrorNumber_TooComplex)
/* Ensure each ATA transfer is a multiple of the sector size (the ATA
* driver is unaware of the sector size, so may have suggested an
* invalid transfer length).
remain = remain & ~((1<<dr->log2_sector_size)-1);
if (!remain)
/* Something's gone wrong, give up now */
dprintf("TooComplex error forced transfer length to zero\n");
transfer_length = remain;
e = transfer_with_retries(reason, flags, dr, disc_address, ptr, &remain);
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