Browse Source

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.
master
Sergey Kiselev 3 months ago
parent
commit
b1b291b1b2
  1. 27
      src/libbsdiskinfo.c

27
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);
}

Loading…
Cancel
Save