TkTech / smartie

Pure-python ATA/SATA/ATAPI/SCSI and disk enumeration library for Linux/Windows/OS X.
https://tkte.ch/smartie/
MIT License
11 stars 5 forks source link

SCSI Status not checked or made available after SCSI Command #15

Closed ZakDanger closed 5 months ago

ZakDanger commented 5 months ago

Windows and Linux both support returning a status value for the scsi device after a scsi command is attempted. This is separate to the sense data and is not currently handled by smartie.

On Linux this value comes from 'SGIOHeader.status'. On Windows this value comes from 'SCSIPassThroughDirect.scsi_status'

The values returned by Windows and Linux are different, but they could be mapped onto matching values when returned by smartie. It looks like you aready have the Linux values in "scsi/structures.py" under "class StatusCode(enum.IntEnum):"

class StatusCode(enum.IntEnum):
    """
    The possible values for `SGIOHeader.status`.
    """

    GOOD = 0x00
    CHECK_CONDITION = 0x01
    CONDITION_GOOD = 0x02
    BUSY = 0x04
    INTERMEDIATE_GOOD = 0x08
    INTERMEDIATE_C_GOOD = 0x0A
    RESERVATION_CONFLICT = 0x0C

The values for Windows can be gotten from: https://github.com/9176324/WinDDK/blob/master/7600.16385.1/inc/ddk/scsi.h They are:

//
// SCSI bus status codes.
//

#define SCSISTAT_GOOD                  0x00
#define SCSISTAT_CHECK_CONDITION       0x02
#define SCSISTAT_CONDITION_MET         0x04
#define SCSISTAT_BUSY                  0x08
#define SCSISTAT_INTERMEDIATE          0x10
#define SCSISTAT_INTERMEDIATE_COND_MET 0x14
#define SCSISTAT_RESERVATION_CONFLICT  0x18
#define SCSISTAT_COMMAND_TERMINATED    0x22
#define SCSISTAT_QUEUE_FULL            0x28

If you are already making changes to 'issue_command()' to return a tuple that now includes the data size, perhaps you could also add the scsi status to the tuple.

ZakDanger commented 5 months ago

I thought i should add that every Windows SPTI sample code I've seen calls DeviceIoControl(), then checks that the return value is True and that ScsiStatus is 0 to determine that the command was successful.

It is possible for DeviceIoControl() to return True, but SccsiStatus NOT be zero. In this case the command is treated as unsuccessful.

Here is one such example from the Windows Drive DevKit https://github.com/9176324/WinDDK/blob/master/7600.16385.1/src/storage/tools/spti/spti.c

TkTech commented 5 months ago

The interface for issue_command is going to change a bit, returning an object that has common universal fields (like status) as well as pointers to the platform-specific structs. That should take care of this. At a low level, we don't want to check statuses ourselves or raise exceptions if we can help it, but we should check this field in the higher level API.

TkTech commented 5 months ago

Can you try the changes in main?