Browse Source

SAT: implement 12-byte fallback recovery for legacy JMicron bridges

Introduces an automated 12-byte ATA PASS-THROUGH (12) fallback chain inside
query_cam_properties. If a legacy controller (e.g., JMicron JMS539) silences
the modern 16-byte layout by returning an empty identity payload, the core
safely downgrades the command tracking to 12-byte mapping (0xA1). Additionally,
standardized temperature output parsing for Samsung/Toshiba drive limits.
master v0.1.2
Sergey Kiselev 3 months ago
parent
commit
9002d15a55
  1. 6
      src/cli.c
  2. 30
      src/libbsdiskinfo.c

6
src/cli.c

@ -166,6 +166,12 @@ static void print_smart(const char *disk_name) {
int min_lifetime = (int)((counters[i].raw_val >> 32) & 0xFF); /* Fixed strict & 0xFF byte-4 alignment masking */
int max_lifetime = (int)((counters[i].raw_val >> 40) & 0xFF); /* Fixed strict & 0xFF byte-5 alignment masking */
/* Fix for Toshiba/Samsung layouts where byte 4 is Max and byte 5 is empty */
if (min_lifetime > 0 && max_lifetime == 0) {
max_lifetime = min_lifetime;
min_lifetime = 0;
}
if (min_lifetime > 0 && min_lifetime < 100) {
if (max_lifetime > 0 && max_lifetime < 100 && max_lifetime > min_lifetime) {
printf("%-12llu (Min/Max %d/%d)\n", (unsigned long long)counters[i].raw_val, min_lifetime, max_lifetime);

30
src/libbsdiskinfo.c

@ -296,7 +296,33 @@ static void query_cam_properties(
uint8_t *cdb = ccb->csio.cdb_io.cdb_bytes;
cdb[0] = 0x85; cdb[1] = 4 << 1; cdb[2] = 0x08 | 0x02; cdb[4] = 1; cdb[14] = 0xEC;
if (cam_send_ccb(cam_dev, ccb) == 0 && (ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
int success = (cam_send_ccb(cam_dev, ccb) == 0 && (ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP);
if (success && ident_buf->model[0] == 0) {
success = 0;
}
if (!success) {
/*
* FALLBACK: 16-byte frame returned an empty layout.
* Downgrade transport to 12-byte ATA PASS-THROUGH (12) for legacy JMicron bridges.
*/
memset(&ccb->csio, 0, sizeof(struct ccb_scsiio));
cam_fill_csio(&ccb->csio, 2, NULL, CAM_DIR_IN, CAM_TAG_ACTION_NONE,
(uint8_t *)ident_buf, sizeof(struct ata_params), SSD_FULL_SIZE, 12, 5000);
uint8_t *cdb12 = ccb->csio.cdb_io.cdb_bytes;
cdb12[0] = 0xA1; cdb12[1] = 4 << 1; cdb12[2] = 0x2E; cdb12[4] = 1; cdb12[9] = 0xEC;
if (cam_send_ccb(cam_dev, ccb) == 0) {
uint32_t cam_status = ccb->ccb_h.status & CAM_STATUS_MASK;
if (cam_status == CAM_REQ_CMP || cam_status == CAM_SCSI_STATUS_ERROR) {
success = 1;
}
}
}
if (success) {
/* Extract Identity Block Data fields */
char real_model[41];
memcpy(real_model, ident_buf->model, sizeof(ident_buf->model));
@ -354,7 +380,7 @@ static void query_cam_properties(
}
free(inq_buf);
}
}
/* --- PROTOCOL BRANCH 2: Native SATA/ATA Devices (ada) --- */
else if (strncmp(base_disk, "ada", 3) == 0) {
/* 2a: Pure ATA IDENTIFY */

Loading…
Cancel
Save