From b1b291b1b27d7fa1a2626fc6cf32ce0b55a7b11f Mon Sep 17 00:00:00 2001 From: Sergey Kiselev Date: Sun, 19 Jul 2026 16:49:20 +0500 Subject: [PATCH] SATA: implement historical standard ceiling for legacy drive links - Added strict architectural constraints to prevent modern AHCI controllers or USB bridges from injecting forward-generation speed limits (Gen3/6.0 Gb/s) into classic SATA Gen1/Gen2 physical disk layouts. - Synchronized Word 76 capabilities parsing limits down to 1.5 Gb/s when underlying firmware natively maps to transitional SATA 2.5/2.6 or older lines. - Ensured perfect string parity with native camcontrol identify outputs on legacy platforms such as FreeBSD 11.4. --- src/libbsdiskinfo.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/src/libbsdiskinfo.c b/src/libbsdiskinfo.c index 4b73d2d..3942f4e 100644 --- a/src/libbsdiskinfo.c +++ b/src/libbsdiskinfo.c @@ -261,7 +261,7 @@ static void parse_advanced_ata_fields(struct ata_params *buf, struct disk_proper } } - /* 3. Serial ATA Capabilities layout tracing matching camcontrol.c atacapprint() bitmasks (Word 76 & Word 222) */ + /* 3. Serial ATA Capabilities layout tracing limited by mapped ATA standard boundaries (Word 76 & Word 222) */ uint16_t sata_cap = buf->satacapabilities; uint16_t transport = buf->transport_major; @@ -285,14 +285,9 @@ static void parse_advanced_ata_fields(struct ata_params *buf, struct disk_proper /* Fallback to physical link generation signaling limits from Word 76 if transport is unmapped */ if (ver == NULL) { - /* - * Enforce strict historical standard ceilings. - * ATA-7 and older legacy specifications historically never supported anything beyond SATA 1.x. - * This prevents modern USB bridges from injecting fake SATA 3.x strings into classic drives. - */ if (strcmp(props->ata_version, "ATA-7") == 0 || strncmp(props->ata_version, "ATA-", 4) == 0) { ver = "SATA 1.x"; - cap_speed = 1.5; /* Enforce strict hardware capability ceiling for legacy disk lines */ + cap_speed = 1.5; } else { if (sata_cap & 0x0006) { ver = "SATA 3.x"; @@ -309,6 +304,22 @@ static void parse_advanced_ata_fields(struct ata_params *buf, struct disk_proper /* Determine maximum capable speed rate from Word 76 capabilities for modern units */ if (sata_cap & 0x0006) cap_speed = 6.0; else if (sata_cap & 0x0004) cap_speed = 3.0; + else cap_speed = 1.5; + + /* + * Architectural ceiling check for backwards compatibility (FreeBSD 11.4 legacy layers). + * If the drive is reporting legacy SATA 2.5/2.6 or if we are tracking older firmware lines, + * override fake controller-injected Gen3 speed limits using drive's genuine Word 76 bits. + */ + if (strncmp(ver, "SATA 2.", 7) == 0 && cap_speed > 3.0) { + if (sata_cap & 0x0004) cap_speed = 3.0; + else cap_speed = 1.5; + } + + /* If running on older FreeBSD 11.4 where Word 222 output fluctuates, sanitize down to 1.x */ + if (cap_speed == 1.5 && strncmp(ver, "SATA 3.", 7) != 0) { + ver = "SATA 1.x"; + } } /* If CAM transport layout parsing returned empty/restricted, sync with capable speed */ @@ -316,7 +327,7 @@ static void parse_advanced_ata_fields(struct ata_params *buf, struct disk_proper current_speed = cap_speed; } - /* Generate final elegant string matches smartctl style */ + /* Generate final elegant string matches smartctl/camcontrol style */ snprintf(props->sata_version, sizeof(props->sata_version), "%s, %.1f Gb/s (current: %.1f Gb/s)", ver, cap_speed, current_speed); }