@ -225,6 +225,98 @@ int diskinfo_get_mounts(const char *base_disk, struct disk_mount *mounts_out, in
return match_count ; /* Return absolute count of populated records */
}
/*
* Extracts advanced ATA / SATA hardware descriptor properties from
* the provided native IDENTIFY parameter blocks .
*/
static void parse_advanced_ata_fields ( struct ata_params * buf , struct disk_properties * props ) {
/* Base internal storage fields configuration */
uint16_t ff = buf - > form_factor ;
uint16_t major = buf - > version_major ;
uint16_t transport = buf - > transport_major ; /* Word 222: Transport Major Revision Number */
uint16_t sata_cap = buf - > satacapabilities ; /* Word 76: SATA Capabilities descriptor */
uint16_t sec = buf - > security_status ; /* Word 128: ATA Security Feature Set state */
/* 1. Form Factor dimensions handling (Word 168) */
if ( ff = = 2 ) strlcpy ( props - > form_factor , " 3.5 inches " , sizeof ( props - > form_factor ) ) ;
else if ( ff = = 3 ) strlcpy ( props - > form_factor , " 2.5 inches " , sizeof ( props - > form_factor ) ) ;
else if ( ff = = 4 ) strlcpy ( props - > form_factor , " 1.8 inches " , sizeof ( props - > form_factor ) ) ;
else if ( ff = = 5 ) strlcpy ( props - > form_factor , " less than 1.8 " , sizeof ( props - > form_factor ) ) ;
else strlcpy ( props - > form_factor , " N/A " , sizeof ( props - > form_factor ) ) ;
/* 2. Major ATA Version standard handling (Word 80 & Word 222 Transport Framework) */
if ( major = = 0xFFFF | | major = = 0x0000 ) {
strlcpy ( props - > ata_version , " Unknown " , sizeof ( props - > ata_version ) ) ;
}
/*
* Detect actual ATA / ACS revision specification standard level by
* cross - verifying backward - compatible Word 80 flags against physical Word 222 transport bits .
*/
else if ( ( major & ( 1 < < 14 ) ) | | ( ( major & ( 1 < < 11 ) ) & & ( transport & 0x1000 ) & & ( transport & 0x0040 ) ) ) {
/* Word 80 Bit 14 OR (ATA8-ACS bit + SATA 3.1+ transport bit 12 + SATA 3.3 bit 6) -> ACS-4 */
strlcpy ( props - > ata_version , " ACS-4 " , sizeof ( props - > ata_version ) ) ;
} else if ( ( major & ( 1 < < 13 ) ) | | ( ( major & ( 1 < < 10 ) ) & & ( transport & 0x1000 ) ) ) {
/* Word 80 Bit 13 OR (ATA-7+ bit + SATA 3.1+ transport bit 12) -> ACS-3 */
strlcpy ( props - > ata_version , " ACS-3 " , sizeof ( props - > ata_version ) ) ;
} else if ( major & ( 1 < < 12 ) ) {
strlcpy ( props - > ata_version , " ACS-2 " , sizeof ( props - > ata_version ) ) ;
} else if ( major & ( 1 < < 11 ) ) {
strlcpy ( props - > ata_version , " ATA8-ACS " , sizeof ( props - > ata_version ) ) ;
} else if ( major & ( 1 < < 10 ) ) {
strlcpy ( props - > ata_version , " ATA/ATAPI-7 " , sizeof ( props - > ata_version ) ) ;
} else {
snprintf ( props - > ata_version , sizeof ( props - > ata_version ) , " ATA Minor/Legacy (0x%04X) " , major ) ;
}
/* 3. Serial ATA Capabilities layout tracing (Word 76 & Word 222 Context) */
if ( sata_cap = = 0xFFFF | | sata_cap = = 0x0000 ) {
strlcpy ( props - > sata_version , " Not a SATA device " , sizeof ( props - > sata_version ) ) ;
} else {
const char * ver = " SATA " ;
if ( transport ! = 0xFFFF & & transport ! = 0x0000 & & ( transport & 0x1000 ) ) {
if ( strcmp ( props - > ata_version , " ACS-4 " ) = = 0 ) {
/* ACS-4 devices can scale between SATA 3.2 and SATA 3.3 */
if ( ( transport & ( 1 < < 6 ) ) & & ( transport & 0x0100 ) ) {
ver = " SATA 3.3 " ;
} else {
ver = " SATA 3.2 " ;
}
} else if ( strcmp ( props - > ata_version , " ACS-3 " ) = = 0 ) {
ver = " SATA 3.1 " ;
} else {
if ( sata_cap & 0x0006 ) ver = " SATA 3.0 " ;
else if ( sata_cap & 0x0004 ) ver = " SATA 2.6 " ;
else if ( sata_cap & 0x0002 ) ver = " SATA 1.0a " ;
}
} else {
if ( sata_cap & 0x0006 ) ver = " SATA 3.0 " ;
else if ( sata_cap & 0x0004 ) ver = " SATA 2.6 " ;
else if ( sata_cap & 0x0002 ) ver = " SATA 1.0a " ;
}
/* Append signaling interface speed specs mapping data */
if ( sata_cap & 0x0006 ) {
snprintf ( props - > sata_version , sizeof ( props - > sata_version ) , " %s, 6.0 Gb/s " , ver ) ;
} else if ( sata_cap & 0x0004 ) {
snprintf ( props - > sata_version , sizeof ( props - > sata_version ) , " %s, 3.0 Gb/s " , ver ) ;
} else {
snprintf ( props - > sata_version , sizeof ( props - > sata_version ) , " %s, 1.5 Gb/s " , ver ) ;
}
}
/* 4. ATA Security Feature Set state validation (Word 128) */
if ( ! ( sec & 0x0001 ) ) {
strlcpy ( props - > security_status , " Disabled " , sizeof ( props - > security_status ) ) ;
} else if ( sec & 0x0004 ) {
strlcpy ( props - > security_status , " LOCKED " , sizeof ( props - > security_status ) ) ;
} else if ( sec & 0x0008 ) {
strlcpy ( props - > security_status , " FROZEN " , sizeof ( props - > security_status ) ) ;
} else {
strlcpy ( props - > security_status , " NOT FROZEN " , sizeof ( props - > security_status ) ) ;
}
}
/*
* Internal helper to query the device via FreeBSD libcam .
* Handles SCSI SAT Pass - Through ( 16 ) for ' da ' devices and native ATA for ' ada ' devices .
@ -244,6 +336,12 @@ static void query_cam_properties(
* pt_failed = 0 ;
/* Pre-initialize advanced hardware descriptors with default values */
strlcpy ( props - > form_factor , " N/A " , sizeof ( props - > form_factor ) ) ;
strlcpy ( props - > ata_version , " N/A " , sizeof ( props - > ata_version ) ) ;
strlcpy ( props - > sata_version , " N/A " , sizeof ( props - > sata_version ) ) ;
strlcpy ( props - > security_status , " N/A " , sizeof ( props - > security_status ) ) ;
/* CRITICAL: Must use O_RDWR for transport-layer commands execution path to unlock */
cam_dev = cam_open_device ( base_disk , O_RDWR ) ;
if ( cam_dev = = NULL ) return ;
@ -362,9 +460,14 @@ static void query_cam_properties(
* is_ssd = 0 ;
}
/* Parse Sector Sizes */
if ( ( ident_buf - > pss & 0xC000 ) = = 0x4000 & & ( ident_buf - > pss & 0x1000 ) ) {
/* Parse advanced hardware descriptors from the verified buffer */
parse_advanced_ata_fields ( ident_buf , props ) ;
/* Parse Sector Sizes (Word 106: Physical sector size) */
if ( ( ident_buf - > pss & 0x4000 ) & & ( ident_buf - > pss & 0x2000 ) ) {
props - > physical_sector_size = props - > logical_sector_size * ( 1 < < ( ident_buf - > pss & 0x000F ) ) ;
} else {
props - > physical_sector_size = props - > logical_sector_size ;
}
/* Parse S.M.A.R.T. enablement states */
@ -428,9 +531,14 @@ static void query_cam_properties(
* is_ssd = 0 ;
}
/* Parse Sector Sizes */
if ( ( ident_buf - > pss & 0xC000 ) = = 0x4000 & & ( ident_buf - > pss & 0x1000 ) ) {
/* Parse advanced hardware descriptors from the direct AHCI buffer */
parse_advanced_ata_fields ( ident_buf , props ) ;
/* Parse Sector Sizes (Word 106: Physical sector size) */
if ( ( ident_buf - > pss & 0x4000 ) & & ( ident_buf - > pss & 0x2000 ) ) {
props - > physical_sector_size = props - > logical_sector_size * ( 1 < < ( ident_buf - > pss & 0x000F ) ) ;
} else {
props - > physical_sector_size = props - > logical_sector_size ;
}
/* Parse S.M.A.R.T. enablement states */