Commit f6303321 authored by Jan Koester's avatar Jan Koester
Browse files

test

parent cdfb1c65
Loading
Loading
Loading
Loading
+37 −4
Changes for src/smart.cpp: 37 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -37,7 +37,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <set>

#include <fcntl.h>
#include <scsi/sg.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <linux/nvme_ioctl.h>
@@ -97,6 +96,40 @@ uint64_t le(const uint8_t *p, int n) {

// ─── ATA over SG_IO (ATA PASS-THROUGH (16), SAT) ────────────────────────────

// The SG_IO interface of the kernel's sd/sg drivers. <scsi/sg.h> is
// glibc's, not a kernel UAPI header (systempp has none): the ioctl and
// struct sg_io_hdr as the kernel defines them (include/scsi/sg.h), a
// stable ABI.
struct SgIoHdr {
    int interface_id;            // 'S'
    int dxfer_direction;         // SgDxfer*
    unsigned char cmd_len;
    unsigned char mx_sb_len;     // sense buffer size
    unsigned short iovec_count;
    unsigned int dxfer_len;
    void *dxferp;
    unsigned char *cmdp;
    void *sbp;
    unsigned int timeout;        // ms
    unsigned int flags;
    int pack_id;
    void *usr_ptr;
    unsigned char status;        // SCSI status
    unsigned char masked_status;
    unsigned char msg_status;
    unsigned char sb_len_wr;     // sense bytes written
    unsigned short host_status;
    unsigned short driver_status;
    int resid;
    unsigned int duration;
    unsigned int info;
};
static_assert(sizeof(SgIoHdr) == (sizeof(void *) == 8 ? 88 : 64), "struct sg_io_hdr layout");

constexpr unsigned long SgIo = 0x2285;  // SG_IO
constexpr int SgDxferNone = -1;         // SG_DXFER_NONE
constexpr int SgDxferFromDev = -3;      // SG_DXFER_FROM_DEV

struct AtaCmd {
    uint8_t command = 0, features = 0, count = 0, lbaLow = 0, lbaMid = 0, lbaHigh = 0, device = 0;
};
@@ -119,9 +152,9 @@ bool ata(int fd, const AtaCmd &c, uint8_t *data, AtaRegs *regs, std::string &err
    cdb[13] = c.device;
    cdb[14] = c.command;
    uint8_t sense[32] = {};
    sg_io_hdr io{};
    SgIoHdr io{};
    io.interface_id = 'S';
    io.dxfer_direction = data ? SG_DXFER_FROM_DEV : SG_DXFER_NONE;
    io.dxfer_direction = data ? SgDxferFromDev : SgDxferNone;
    io.cmd_len = sizeof(cdb);
    io.cmdp = cdb;
    io.mx_sb_len = sizeof(sense);
@@ -129,7 +162,7 @@ bool ata(int fd, const AtaCmd &c, uint8_t *data, AtaRegs *regs, std::string &err
    io.dxfer_len = data ? 512 : 0;
    io.dxferp = data;
    io.timeout = 15000;
    if (ioctl(fd, SG_IO, &io) < 0) {
    if (ioctl(fd, SgIo, &io) < 0) {
        err = blk::sysErr("SG_IO", errno);
        return false;
    }