mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-10-29 16:26:39 +01:00
PhysicalDisk (NetBSD/OpenBSD): adds debug logs
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#include "physicaldisk.h"
|
||||
#include "common/io.h"
|
||||
#include "common/sysctl.h"
|
||||
#include "common/debug.h"
|
||||
|
||||
#include <util.h>
|
||||
#include <prop/proplib.h>
|
||||
@@ -14,21 +15,101 @@
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
static inline const char* retstsToStr(uint8_t retsts) {
|
||||
switch (retsts) {
|
||||
case SCCMD_OK: return "OK";
|
||||
case SCCMD_TIMEOUT: return "TIMEOUT";
|
||||
case SCCMD_BUSY: return "BUSY";
|
||||
case SCCMD_SENSE: return "SENSE";
|
||||
case SCCMD_UNKNOWN: return "UNKNOWN";
|
||||
default: return "?";
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
static inline const char* senseKeyToStr(uint8_t key) {
|
||||
switch (key) {
|
||||
case 0x0: return "No Sense";
|
||||
case 0x1: return "Recovered Error";
|
||||
case 0x2: return "Not Ready";
|
||||
case 0x3: return "Medium Error";
|
||||
case 0x4: return "Hardware Error";
|
||||
case 0x5: return "Illegal Request";
|
||||
case 0x6: return "Unit Attention";
|
||||
case 0x7: return "Data Protect";
|
||||
case 0x8: return "Blank Check";
|
||||
case 0x9: return "Vendor Specific";
|
||||
case 0xA: return "Copy Aborted";
|
||||
case 0xB: return "Aborted Command";
|
||||
case 0xC: return "Equal";
|
||||
case 0xD: return "Volume Overflow";
|
||||
case 0xE: return "Miscompare";
|
||||
case 0xF: return "Completed";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static void logScsiSense(const char* diskName, const char* operation, const scsireq_t* req) {
|
||||
uint8_t responseCode = req->sense[0] & 0x7F;
|
||||
uint8_t senseKey;
|
||||
uint8_t asc;
|
||||
uint8_t ascq;
|
||||
|
||||
if (responseCode == 0x72 || responseCode == 0x73) {
|
||||
senseKey = req->sense[1] & 0x0F;
|
||||
asc = req->sense[2];
|
||||
ascq = req->sense[3];
|
||||
} else {
|
||||
senseKey = req->sense[2] & 0x0F;
|
||||
asc = req->sense[12];
|
||||
ascq = req->sense[13];
|
||||
}
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY rawSense = ffStrbufCreate();
|
||||
for (size_t i = 0; i < req->senselen_used; ++i) {
|
||||
if (i)
|
||||
ffStrbufAppendC(&rawSense, ' ');
|
||||
ffStrbufAppendF(&rawSense, "%02X", req->sense[i]);
|
||||
}
|
||||
|
||||
FF_DEBUG(
|
||||
"%s for %s reported SENSE: response=0x%02X, key=0x%X (%s), ASC=0x%02X, ASCQ=0x%02X, raw=[%s]",
|
||||
operation,
|
||||
diskName,
|
||||
responseCode,
|
||||
senseKey,
|
||||
senseKeyToStr(senseKey),
|
||||
asc,
|
||||
ascq,
|
||||
rawSense.length ? rawSense.chars : "empty"
|
||||
);
|
||||
}
|
||||
#else
|
||||
#define logScsiSense(...) ((void)0)
|
||||
#endif
|
||||
|
||||
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options) {
|
||||
FF_STRBUF_AUTO_DESTROY diskNames = ffStrbufCreate();
|
||||
FF_DEBUG("Querying disk names via sysctl hw.disknames");
|
||||
const char* error = ffSysctlGetString("hw.disknames", &diskNames);
|
||||
if (error) {
|
||||
FF_DEBUG("ffSysctlGetString(hw.disknames) failed: %s", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
FF_DEBUG("Disk names: %s", diskNames.chars);
|
||||
|
||||
char* diskName = NULL;
|
||||
size_t len = 0;
|
||||
while (ffStrbufGetdelim(&diskName, &len, ' ', &diskNames)) {
|
||||
FF_DEBUG("Probing disk: %s", diskName);
|
||||
|
||||
if (options->namePrefix.length && !ffStrbufStartsWith(&(FFstrbuf) {
|
||||
.chars = diskName,
|
||||
.length = (uint32_t) len,
|
||||
},
|
||||
&options->namePrefix)) {
|
||||
FF_DEBUG("Skipping %s due to namePrefix filter", diskName);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -36,14 +117,19 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||
FF_AUTO_CLOSE_FD int f = opendisk(diskName, O_RDONLY, devPath, ARRAY_SIZE(devPath), 0);
|
||||
if (f < 0) {
|
||||
if (errno == EACCES) {
|
||||
FF_DEBUG("opendisk(%s) failed: permission denied", diskName);
|
||||
return "Permission denied; root required";
|
||||
} else {
|
||||
FF_DEBUG("opendisk(%s) failed: %s", diskName, strerror(errno));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
FF_DEBUG("Opened %s as %s", diskName, devPath);
|
||||
|
||||
struct disklabel dl;
|
||||
if (ioctl(f, DIOCGDINFO, &dl) < 0) {
|
||||
FF_DEBUG("ioctl(DIOCGDINFO) failed for %s: %s", diskName, strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -53,6 +139,7 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||
|
||||
prop_dictionary_t dict = NULL;
|
||||
if (prop_dictionary_recv_ioctl(f, DIOCGDISKINFO, &dict) == 0) {
|
||||
FF_DEBUG("DIOCGDISKINFO succeeded for %s", diskName);
|
||||
prop_dictionary_get_string(dict, "type", &devType);
|
||||
|
||||
prop_dictionary_t geometry;
|
||||
@@ -60,10 +147,12 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||
prop_dictionary_get_ulong(geometry, "sectors-per-unit", §orsPerUnit);
|
||||
prop_dictionary_get_ulong(geometry, "sector-size", §orSize);
|
||||
} else {
|
||||
FF_DEBUG("No geometry in diskinfo for %s, falling back to disklabel", diskName);
|
||||
sectorsPerUnit = dl.d_secperunit;
|
||||
sectorSize = dl.d_secsize;
|
||||
}
|
||||
} else {
|
||||
FF_DEBUG("DIOCGDISKINFO failed for %s, falling back to disklabel", diskName);
|
||||
sectorsPerUnit = dl.d_secperunit;
|
||||
sectorSize = dl.d_secsize;
|
||||
}
|
||||
@@ -80,6 +169,7 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||
case DKTYPE_RUMPD:
|
||||
case DKTYPE_MD: {
|
||||
if (options->hideType & FF_PHYSICALDISK_TYPE_VIRTUAL) {
|
||||
FF_DEBUG("Skipping virtual disk %s due to hideType", diskName);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -91,6 +181,7 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||
uint64_t size = sectorsPerUnit * sectorSize;
|
||||
if (size == 0) {
|
||||
if (options->hideType & FF_PHYSICALDISK_TYPE_UNUSED) {
|
||||
FF_DEBUG("Skipping unused disk %s due to hideType", diskName);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -106,6 +197,11 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||
device->type = type;
|
||||
device->size = size;
|
||||
device->temperature = FF_PHYSICALDISK_TEMP_UNSET;
|
||||
FF_DEBUG("Added disk entry: name='%s', devPath='%s', interconnect='%s', size=%llu",
|
||||
device->name.chars,
|
||||
device->devPath.chars,
|
||||
device->interconnect.chars,
|
||||
(unsigned long long) device->size);
|
||||
|
||||
if (dict) {
|
||||
prop_object_release(dict);
|
||||
@@ -121,21 +217,28 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||
.timeout = 1000,
|
||||
.flags = SCCMD_READ,
|
||||
};
|
||||
if (ioctl(f, SCIOCCOMMAND, &req) == 0 && req.retsts == SCCMD_OK) {
|
||||
ffStrbufClear(&device->name);
|
||||
ffStrbufAppendNS(&device->name, (uint32_t) ARRAY_SIZE(inquiry.vendor), inquiry.vendor);
|
||||
ffStrbufTrimRight(&device->name, '\0');
|
||||
ffStrbufTrimRight(&device->name, ' ');
|
||||
ffStrbufTrimRight(&device->name, ',');
|
||||
ffStrbufAppendC(&device->name, ' ');
|
||||
ffStrbufAppendNS(&device->name, (uint32_t) ARRAY_SIZE(inquiry.product), inquiry.product);
|
||||
ffStrbufTrimRight(&device->name, '\0');
|
||||
ffStrbufTrimRight(&device->name, ' ');
|
||||
if (ioctl(f, SCIOCCOMMAND, &req) == 0) {
|
||||
if (req.retsts == SCCMD_OK) {
|
||||
ffStrbufClear(&device->name);
|
||||
ffStrbufAppendNS(&device->name, (uint32_t) ARRAY_SIZE(inquiry.vendor), inquiry.vendor);
|
||||
ffStrbufTrimRight(&device->name, '\0');
|
||||
ffStrbufTrimRight(&device->name, ' ');
|
||||
ffStrbufTrimRight(&device->name, ',');
|
||||
ffStrbufAppendC(&device->name, ' ');
|
||||
ffStrbufAppendNS(&device->name, (uint32_t) ARRAY_SIZE(inquiry.product), inquiry.product);
|
||||
ffStrbufTrimRight(&device->name, '\0');
|
||||
ffStrbufTrimRight(&device->name, ' ');
|
||||
|
||||
ffStrbufSetNS(&device->revision, (uint32_t) ARRAY_SIZE(inquiry.revision), inquiry.revision);
|
||||
ffStrbufTrimRight(&device->name, '\0');
|
||||
ffStrbufTrimRight(&device->revision, ' ');
|
||||
ffStrbufSetNS(&device->revision, (uint32_t) ARRAY_SIZE(inquiry.revision), inquiry.revision);
|
||||
ffStrbufTrimRight(&device->name, '\0');
|
||||
ffStrbufTrimRight(&device->revision, ' ');
|
||||
FF_DEBUG("SCSI inquiry for %s: name='%s', revision='%s'", diskName, device->name.chars, device->revision.chars);
|
||||
} else {
|
||||
FF_DEBUG("SCSI inquiry retsts != SCCMD_OK for %s (%d)", diskName, req.retsts);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
FF_DEBUG("ioctl(SCIOCCOMMAND) failed for SCSI inquiry on %s: %s", diskName, strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -152,11 +255,20 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||
.timeout = 1000,
|
||||
.flags = SCCMD_READ,
|
||||
};
|
||||
if (ioctl(f, SCIOCCOMMAND, &req) == 0 && req.retsts == SCCMD_OK && evpd.header.pagecode == SINQ_VPD_UNIT_SERIAL) {
|
||||
for (uint8_t i = 0; i < evpd.header.length[1]; ++i) {
|
||||
ffStrbufAppendF(&device->serial, "%02X", evpd.body.serial_number[i]);
|
||||
if (ioctl(f, SCIOCCOMMAND, &req) == 0) {
|
||||
if (req.retsts == SCCMD_OK && evpd.header.pagecode == SINQ_VPD_UNIT_SERIAL) {
|
||||
for (uint8_t i = 0; i < evpd.header.length[1]; ++i) {
|
||||
ffStrbufAppendF(&device->serial, "%02X", evpd.body.serial_number[i]);
|
||||
}
|
||||
ffStrbufTrimRight(&device->serial, ' ');
|
||||
FF_DEBUG("SCSI serial for %s: %s", diskName, device->serial.chars);
|
||||
} else if (req.retsts == SCCMD_SENSE) {
|
||||
logScsiSense(diskName, "SCSI serial page", &req);
|
||||
} else {
|
||||
FF_DEBUG("SCSI serial page unavailable for %s (retsts=%s, pagecode=%u)", diskName, retstsToStr(req.retsts), (unsigned) evpd.header.pagecode);
|
||||
}
|
||||
ffStrbufTrimRight(&device->serial, ' ');
|
||||
} else {
|
||||
FF_DEBUG("ioctl(SCIOCCOMMAND) failed for SCSI serial on %s: %s", diskName, strerror(errno));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -169,9 +281,20 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||
.timeout = 1000,
|
||||
.flags = SCCMD_READ,
|
||||
};
|
||||
if (ioctl(f, SCIOCCOMMAND, &req) == 0 && req.retsts == SCCMD_OK && mode.data_length > 0) {
|
||||
device->type |= mode.dev_spec & 0x80 ? FF_PHYSICALDISK_TYPE_READONLY : FF_PHYSICALDISK_TYPE_READWRITE;
|
||||
if (ioctl(f, SCIOCCOMMAND, &req) == 0) {
|
||||
if (req.retsts == SCCMD_OK && mode.data_length > 0) {
|
||||
device->type |= mode.dev_spec & 0x80 ? FF_PHYSICALDISK_TYPE_READONLY : FF_PHYSICALDISK_TYPE_READWRITE;
|
||||
FF_DEBUG("SCSI mode for %s indicates: %s", diskName, mode.dev_spec & 0x80 ? "readonly" : "readwrite");
|
||||
} else if (req.retsts == SCCMD_SENSE) {
|
||||
logScsiSense(diskName, "SCSI mode sense", &req);
|
||||
} else {
|
||||
FF_DEBUG("SCSI mode sense unavailable for %s (retsts=%s, data_length=%u)", diskName, retstsToStr(req.retsts), (unsigned) mode.data_length);
|
||||
}
|
||||
} else {
|
||||
FF_DEBUG("ioctl(SCIOCCOMMAND) failed for SCSI mode sense on %s: %s", diskName, strerror(errno));
|
||||
}
|
||||
|
||||
FF_DEBUG("Detected disk '%s' (%s), type=%u", device->name.chars, diskName, (unsigned) device->type);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "physicaldisk.h"
|
||||
#include "common/io.h"
|
||||
#include "common/sysctl.h"
|
||||
#include "common/debug.h"
|
||||
|
||||
#include <util.h>
|
||||
#include <sys/ioctl.h>
|
||||
@@ -11,13 +12,90 @@
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
|
||||
static inline const char* retstsToStr(uint8_t retsts) {
|
||||
switch (retsts) {
|
||||
case SCCMD_OK: return "OK";
|
||||
case SCCMD_TIMEOUT: return "TIMEOUT";
|
||||
case SCCMD_BUSY: return "BUSY";
|
||||
case SCCMD_SENSE: return "SENSE";
|
||||
case SCCMD_UNKNOWN: return "UNKNOWN";
|
||||
default: return "?";
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
static inline const char* senseKeyToStr(uint8_t key) {
|
||||
switch (key) {
|
||||
case 0x0: return "No Sense";
|
||||
case 0x1: return "Recovered Error";
|
||||
case 0x2: return "Not Ready";
|
||||
case 0x3: return "Medium Error";
|
||||
case 0x4: return "Hardware Error";
|
||||
case 0x5: return "Illegal Request";
|
||||
case 0x6: return "Unit Attention";
|
||||
case 0x7: return "Data Protect";
|
||||
case 0x8: return "Blank Check";
|
||||
case 0x9: return "Vendor Specific";
|
||||
case 0xA: return "Copy Aborted";
|
||||
case 0xB: return "Aborted Command";
|
||||
case 0xC: return "Equal";
|
||||
case 0xD: return "Volume Overflow";
|
||||
case 0xE: return "Miscompare";
|
||||
case 0xF: return "Completed";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static void logScsiSense(const char* diskName, const char* operation, const scsireq_t* req) {
|
||||
uint8_t responseCode = req->sense[0] & 0x7F;
|
||||
uint8_t senseKey;
|
||||
uint8_t asc;
|
||||
uint8_t ascq;
|
||||
|
||||
if (responseCode == 0x72 || responseCode == 0x73) {
|
||||
senseKey = req->sense[1] & 0x0F;
|
||||
asc = req->sense[2];
|
||||
ascq = req->sense[3];
|
||||
} else {
|
||||
senseKey = req->sense[2] & 0x0F;
|
||||
asc = req->sense[12];
|
||||
ascq = req->sense[13];
|
||||
}
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY rawSense = ffStrbufCreate();
|
||||
for (size_t i = 0; i < req->senselen_used; ++i) {
|
||||
if (i)
|
||||
ffStrbufAppendC(&rawSense, ' ');
|
||||
ffStrbufAppendF(&rawSense, "%02X", req->sense[i]);
|
||||
}
|
||||
|
||||
FF_DEBUG(
|
||||
"%s for %s reported SENSE: response=0x%02X, key=0x%X (%s), ASC=0x%02X, ASCQ=0x%02X, raw=[%s]",
|
||||
operation,
|
||||
diskName,
|
||||
responseCode,
|
||||
senseKey,
|
||||
senseKeyToStr(senseKey),
|
||||
asc,
|
||||
ascq,
|
||||
rawSense.length ? rawSense.chars : "empty"
|
||||
);
|
||||
}
|
||||
#else
|
||||
#define logScsiSense(...) ((void)0)
|
||||
#endif
|
||||
|
||||
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options) {
|
||||
FF_STRBUF_AUTO_DESTROY diskNames = ffStrbufCreate();
|
||||
FF_DEBUG("Querying disk names via sysctl hw.disknames");
|
||||
const char* error = ffSysctlGetString(CTL_HW, HW_DISKNAMES, &diskNames);
|
||||
if (error) {
|
||||
FF_DEBUG("ffSysctlGetString(HW_DISKNAMES) failed: %s", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
FF_DEBUG("Disk names: %s", diskNames.chars);
|
||||
|
||||
char* diskName = NULL;
|
||||
size_t len = 0;
|
||||
while (ffStrbufGetdelim(&diskName, &len, ',', &diskNames)) {
|
||||
@@ -26,11 +104,14 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||
*colon = '\0';
|
||||
}
|
||||
|
||||
FF_DEBUG("Probing disk: %s", diskName);
|
||||
|
||||
if (options->namePrefix.length && !ffStrbufStartsWith(&(FFstrbuf) {
|
||||
.chars = diskName,
|
||||
.length = (uint32_t) len,
|
||||
},
|
||||
&options->namePrefix)) {
|
||||
FF_DEBUG("Skipping %s due to namePrefix filter", diskName);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -38,20 +119,26 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||
FF_AUTO_CLOSE_FD int f = opendev(diskName, O_RDONLY, OPENDEV_PART, &devPath);
|
||||
if (f < 0) {
|
||||
if (errno == EACCES) {
|
||||
FF_DEBUG("opendev(%s) failed: permission denied", diskName);
|
||||
return "Permission denied; root required";
|
||||
} else {
|
||||
FF_DEBUG("opendev(%s) failed: %s", diskName, strerror(errno));
|
||||
continue; // Unknown error
|
||||
}
|
||||
}
|
||||
|
||||
FF_DEBUG("Opened %s as %s", diskName, devPath);
|
||||
|
||||
struct disklabel dl;
|
||||
if (ioctl(f, DIOCGPDINFO, &dl) < 0) {
|
||||
FF_DEBUG("ioctl(DIOCGPDINFO) failed for %s: %s", diskName, strerror(errno));
|
||||
continue;
|
||||
}
|
||||
|
||||
FFPhysicalDiskType type = FF_PHYSICALDISK_TYPE_NONE;
|
||||
if (dl.d_type == DTYPE_VND || dl.d_type == DTYPE_RDROOT) {
|
||||
if (options->hideType & FF_PHYSICALDISK_TYPE_VIRTUAL) {
|
||||
FF_DEBUG("Skipping virtual disk %s due to hideType", diskName);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -61,6 +148,7 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||
uint64_t size = DL_GETDSIZE(&dl) * dl.d_secsize;
|
||||
if (size == 0) {
|
||||
if (options->hideType & FF_PHYSICALDISK_TYPE_UNUSED) {
|
||||
FF_DEBUG("Skipping unused disk %s due to hideType", diskName);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -76,6 +164,11 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||
device->type = type;
|
||||
device->size = size;
|
||||
device->temperature = FF_PHYSICALDISK_TEMP_UNSET;
|
||||
FF_DEBUG("Added disk entry: name='%s', devPath='%s', interconnect='%s', size=%llu",
|
||||
device->name.chars,
|
||||
device->devPath.chars,
|
||||
device->interconnect.chars,
|
||||
(unsigned long long) device->size);
|
||||
|
||||
struct scsi_inquiry_data inquiry = {};
|
||||
struct scsireq req = {
|
||||
@@ -86,20 +179,28 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||
.timeout = 1000,
|
||||
.flags = SCCMD_READ,
|
||||
};
|
||||
if (ioctl(f, SCIOCCOMMAND, &req) == 0 && req.retsts == SCCMD_OK) {
|
||||
ffStrbufClear(&device->name);
|
||||
ffStrbufAppendNS(&device->name, (uint32_t) ARRAY_SIZE(inquiry.vendor), inquiry.vendor);
|
||||
ffStrbufTrimRight(&device->name, '\0');
|
||||
ffStrbufTrimRight(&device->name, ' ');
|
||||
ffStrbufAppendC(&device->name, ' ');
|
||||
ffStrbufAppendNS(&device->name, (uint32_t) ARRAY_SIZE(inquiry.product), inquiry.product);
|
||||
ffStrbufTrimRight(&device->name, '\0');
|
||||
ffStrbufTrimRight(&device->name, ' ');
|
||||
if (ioctl(f, SCIOCCOMMAND, &req) == 0) {
|
||||
if (req.retsts == SCCMD_OK) {
|
||||
|
||||
ffStrbufSetNS(&device->revision, (uint32_t) ARRAY_SIZE(inquiry.revision), inquiry.revision);
|
||||
ffStrbufTrimRight(&device->revision, '\0');
|
||||
ffStrbufTrimRight(&device->revision, ' ');
|
||||
device->type |= inquiry.dev_qual2 & SID_REMOVABLE ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED;
|
||||
ffStrbufClear(&device->name);
|
||||
ffStrbufAppendNS(&device->name, (uint32_t) ARRAY_SIZE(inquiry.vendor), inquiry.vendor);
|
||||
ffStrbufTrimRight(&device->name, '\0');
|
||||
ffStrbufTrimRight(&device->name, ' ');
|
||||
ffStrbufAppendC(&device->name, ' ');
|
||||
ffStrbufAppendNS(&device->name, (uint32_t) ARRAY_SIZE(inquiry.product), inquiry.product);
|
||||
ffStrbufTrimRight(&device->name, '\0');
|
||||
ffStrbufTrimRight(&device->name, ' ');
|
||||
|
||||
ffStrbufSetNS(&device->revision, (uint32_t) ARRAY_SIZE(inquiry.revision), inquiry.revision);
|
||||
ffStrbufTrimRight(&device->revision, '\0');
|
||||
ffStrbufTrimRight(&device->revision, ' ');
|
||||
device->type |= inquiry.dev_qual2 & SID_REMOVABLE ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED;
|
||||
FF_DEBUG("SCSI inquiry for %s: name='%s', revision='%s'", diskName, device->name.chars, device->revision.chars);
|
||||
} else {
|
||||
FF_DEBUG("SCSI inquiry retsts != SCCMD_OK for %s (%d)", diskName, req.retsts);
|
||||
}
|
||||
} else {
|
||||
FF_DEBUG("ioctl(SCIOCCOMMAND) failed for SCSI inquiry on %s: %s", diskName, strerror(errno));
|
||||
}
|
||||
|
||||
struct scsi_vpd_serial evpd = {};
|
||||
@@ -111,11 +212,20 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||
.timeout = 1000,
|
||||
.flags = SCCMD_READ,
|
||||
};
|
||||
if (ioctl(f, SCIOCCOMMAND, &req) == 0 && req.retsts == SCCMD_OK && evpd.hdr.page_code == SI_PG_SERIAL) {
|
||||
for (uint8_t i = 0; i < evpd.hdr.page_length[1]; ++i) {
|
||||
ffStrbufAppendF(&device->serial, "%02X", evpd.serial[i]);
|
||||
if (ioctl(f, SCIOCCOMMAND, &req) == 0) {
|
||||
if (req.retsts == SCCMD_OK && evpd.hdr.page_code == SI_PG_SERIAL) {
|
||||
for (uint8_t i = 0; i < evpd.hdr.page_length[1]; ++i) {
|
||||
ffStrbufAppendF(&device->serial, "%02X", evpd.serial[i]);
|
||||
}
|
||||
ffStrbufTrimSpace(&device->serial);
|
||||
FF_DEBUG("SCSI serial for %s: %s", diskName, device->serial.chars);
|
||||
} else if (req.retsts == SCCMD_SENSE) {
|
||||
logScsiSense(diskName, "SCSI serial page", &req);
|
||||
} else {
|
||||
FF_DEBUG("SCSI serial page unavailable for %s (retsts=%s, pagecode=%u)", diskName, retstsToStr(req.retsts), (unsigned) evpd.hdr.page_code);
|
||||
}
|
||||
ffStrbufTrimSpace(&device->serial);
|
||||
} else {
|
||||
FF_DEBUG("ioctl(SCIOCCOMMAND) failed for SCSI serial on %s: %s", diskName, strerror(errno));
|
||||
}
|
||||
|
||||
struct scsi_mode_header mode = {};
|
||||
@@ -127,9 +237,20 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||
.timeout = 1000,
|
||||
.flags = SCCMD_READ,
|
||||
};
|
||||
if (ioctl(f, SCIOCCOMMAND, &req) == 0 && req.retsts == SCCMD_OK && mode.data_length > 0) {
|
||||
device->type |= mode.dev_spec & 0x80 ? FF_PHYSICALDISK_TYPE_READONLY : FF_PHYSICALDISK_TYPE_READWRITE;
|
||||
if (ioctl(f, SCIOCCOMMAND, &req) == 0) {
|
||||
if (req.retsts == SCCMD_OK) {
|
||||
device->type |= mode.dev_spec & 0x80 ? FF_PHYSICALDISK_TYPE_READONLY : FF_PHYSICALDISK_TYPE_READWRITE;
|
||||
FF_DEBUG("SCSI mode for %s indicates: %s", diskName, mode.dev_spec & 0x80 ? "readonly" : "readwrite");
|
||||
} else if (req.retsts == SCCMD_SENSE) {
|
||||
logScsiSense(diskName, "SCSI mode sense", &req);
|
||||
} else {
|
||||
FF_DEBUG("SCSI mode sense unavailable for %s (retsts=%s, data_length=%u)", diskName, retstsToStr(req.retsts), (unsigned) mode.data_length);
|
||||
}
|
||||
} else {
|
||||
FF_DEBUG("ioctl(SCIOCCOMMAND) failed for SCSI mode sense on %s: %s", diskName, strerror(errno));
|
||||
}
|
||||
|
||||
FF_DEBUG("Detected disk '%s' (%s), type=%u", device->name.chars, diskName, (unsigned) device->type);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
Reference in New Issue
Block a user