11#ifndef DEV_INTERFACE_H
12#define DEV_INTERFACE_H
14#define DEV_INTERFACE_H_CVSID "$Id: dev_interface.h 5455 2023-02-12 05:13:17Z dpgilbert $\n"
40 device_info(
const char * d_name,
const char * d_type,
const char * r_type)
58 {
no = 0;
msg.erase(); }
69 const char * dev_type,
const char * req_type);
160 bool set_err(
int no,
const char * msg, ...)
165 {
m_err = err;
return false; }
270 operator unsigned char()
const
327 {
m_lo = (
unsigned char) x;
328 m_hi = (
unsigned char)(x >> 8);
331 unsigned short val()
const
333 operator unsigned short()
const
357 m_ll = (
unsigned char) x;
358 m_lm = (
unsigned char)(x >> 8);
359 m_lh = (
unsigned char)(x >> 16);
360 m_hl = (
unsigned char)(x >> 24);
361 m_hm = (
unsigned char)(x >> 32);
362 m_hh = (
unsigned char)(x >> 40);
368 return ( (
unsigned)
m_ll
369 | ((
unsigned)
m_lm << 8)
370 | ((
unsigned)
m_lh << 16)
371 | ((
unsigned)
m_hl << 24)
372 | ((uint64_t)
m_hm << 32)
373 | ((uint64_t)
m_hh << 40));
376 operator uint64_t()
const
479 size = nsectors * 512;
485 buffer =
const_cast<void *
>(buf);
488 size = nsectors * 512;
498 size = nsectors * 512;
546 const char * type = 0);
551 bool data_out_support =
false,
552 bool multi_sector_support =
false,
553 bool ata_48bit_support =
false)
596 const char * msg =
"");
616 bool for_lsense_spc =
false)
const;
670 {
return (
opcode & 0x3); }
677 throw std::logic_error(
"invalid opcode for DATA IN");
804 operator bool()
const
816 {
throw std::logic_error(
"any_device_auto_ptr: wrong usage"); }
842 for (
unsigned i = 0; i <
m_list.size(); i++)
853 for (
unsigned i = 0; i <
m_list.size(); i++)
860 {
m_list.push_back(dev); }
883 for (
unsigned i = 0; i < devlist.
size(); i++) {
962 bool set_err(
int no,
const char * msg, ...)
970 decltype(
nullptr)
set_err_np(
int no, const
char * msg, ...)
975 {
m_err = err;
return false; }
1008 const char * pattern = 0);
1089 const unsigned char * inqdata,
unsigned inqsize);
Smart pointer class for device pointers.
device_type * release()
Return the pointer and release ownership.
~any_device_auto_ptr()
Destructor deletes device object.
void reset()
Delete device object and clear the pointer.
device_type * get() const
Return the pointer.
void replace(device_type *dev)
Replace the pointer.
void operator=(const any_device_auto_ptr< Dev > &)
void operator=(device_type *dev)
Assign a new pointer.
bool operator!() const
For (ptr == 0) check.
any_device_auto_ptr(device_type *dev=0, smart_device *base_dev=0)
Construct from optional pointer to device and optional pointer to base device.
device_type * operator->() const
Pointer dereferencing.
device_type & operator*() const
Pointer dereferencing.
smart_device * m_base_dev
any_device_auto_ptr(const any_device_auto_ptr< Dev > &)
ata_device()
Default constructor, registers device as ATA.
virtual bool ata_identify_is_cached() const
Return true if OS caches ATA identify sector.
bool ata_cmd_is_supported(const ata_cmd_in &in, unsigned flags, const char *type=0)
Check command input parameters.
void hide_ata(bool hide=true)
Hide/unhide ATA interface.
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out)=0
ATA pass through.
bool ata_cmd_is_ok(const ata_cmd_in &in, bool data_out_support=false, bool multi_sector_support=false, bool ata_48bit_support=false)
Check command input parameters (old version).
16-bit alias to a 8-bit ATA register pair.
ata_reg_alias_16(const ata_reg_alias_16 &)
unsigned short val() const
ata_reg_alias_16(ata_register &lo, ata_register &hi)
ata_reg_alias_16 & operator=(unsigned short x)
void operator=(const ata_reg_alias_16 &)
48-bit alias to six 8-bit ATA registers (for LBA).
ata_reg_alias_48 & operator=(uint64_t x)
void operator=(const ata_reg_alias_48 &)
ata_reg_alias_48(ata_register &ll, ata_register &lm, ata_register &lh, ata_register &hl, ata_register &hm, ata_register &hh)
ata_reg_alias_48(const ata_reg_alias_48 &)
ATA register value and info whether it has ever been set.
unsigned char val() const
ata_register & operator=(unsigned char x)
unsigned char m_val
Register value.
unsigned get_nsid() const
Get namespace id.
nvme_device(unsigned nsid)
Constructor requires namespace ID, registers device as NVMe.
virtual bool nvme_pass_through(const nvme_cmd_in &in, nvme_cmd_out &out)=0
NVMe pass through.
bool set_nvme_err(nvme_cmd_out &out, unsigned status, const char *msg=0)
Set last error number and message if pass-through returns NVMe error status.
void hide_nvme(bool hide=true)
Hide/unhide NVMe interface.
void set_nsid(unsigned nsid)
Set namespace id.
scsi_cmd_support logsense_spc_sup
scsi_device()
Default constructor, registers device as SCSI.
bool is_spc4_or_higher() const
bool checked_cmd_support() const
scsi_cmd_support rdefect12_sup
void hide_scsi(bool hide=true)
Hide/unhide SCSI interface.
void set_rcap16_first()
Always try READ CAPACITY(10) (rcap10) first but once we know rcap16 is needed, use it instead.
bool scsi_pass_through_and_check(scsi_cmnd_io *iop, const char *msg="")
scsi_cmd_support logsense_sup
scsi_cmd_support rsoc_sup
virtual bool scsi_pass_through(scsi_cmnd_io *iop)=0
SCSI pass through.
scsi_cmd_support rdefect10_sup
scsi_cmd_support rcap16_sup
enum scsi_cmd_support cmd_support_level(uint8_t opcode, bool sa_valid, uint16_t sa, bool for_lsense_spc=false) const
void set_spc4_or_higher()
List of devices for DEVICESCAN.
const smart_device * at(unsigned i) const
smart_device * at(unsigned i)
void operator=(const smart_device_list &)
void push_back(smart_device *dev)
std::vector< smart_device * > m_list
void push_back(smart_device_auto_ptr &dev)
void append(smart_device_list &devlist)
smart_device_list(const smart_device_list &)
smart_device * release(unsigned i)
Base class for all devices.
bool is_scsi() const
Return true if SCSI device.
int get_errno() const
Get last error number.
const error_info & get_err() const
Get last error info struct.
virtual void release(const smart_device *dev)
Release ownership of other device.
smart_device(const smart_device &)
virtual bool is_powered_down()
Early test if device is powered up or down.
bool is_nvme() const
Return true if NVMe device.
const device_info & get_info() const
Get device info struct.
const smart_interface * smi() const
Get interface which produced this object (const).
smart_interface * smi()
Get interface which produced this object.
const char * get_req_type() const
Get type requested by user, empty if none.
const ata_device * to_ata() const
Downcast to ATA device (const).
const scsi_device * to_scsi() const
Downcast to SCSI device (const).
void operator=(const smart_device &)
const nvme_device * to_nvme() const
Downcast to NVMe device (const).
const char * get_dev_type() const
Get device type.
const char * get_errmsg() const
Get last error message.
virtual bool close()=0
Close device, return false on error.
nvme_device * to_nvme()
Downcast to NVMe device.
bool set_err(int no, const char *msg,...) __attribute_format_printf(3
Set last error number and message.
ata_device * to_ata()
Downcast to ATA device.
do_not_use_in_implementation_classes
Dummy enum for dummy constructor.
const char * get_info_name() const
Get informal name.
virtual smart_device * autodetect_open()
Open device with autodetection support.
scsi_device * to_scsi()
Downcast to SCSI device.
static int get_num_objects()
Get current number of allocated 'smart_device' objects.
virtual bool owns(const smart_device *dev) const
Return true if other device is owned by this device.
virtual bool is_syscall_unsup() const
Return true if last error indicates an unsupported system call.
virtual bool is_open() const =0
Return true if device is open.
bool is_ata() const
Return true if ATA device.
device_info & set_info()
R/W access to device info struct.
const char * get_dev_name() const
Get device (path)name.
virtual bool open()=0
Open device, return false on error.
void clear_err()
Clear last error info.
The platform interface abstraction.
virtual std::string get_app_examples(const char *appname)
Return example string for program 'appname'.
smart_interface(const smart_interface &)
static void set(smart_interface *intf)
Set interface to use, must be called from init().
virtual const char * get_msg_for_errno(int no)
Convert error number into message, used by set_err(no).
void clear_err()
Clear last error info.
virtual nvme_device * get_snt_device(const char *type, scsi_device *scsidev)
Return NVMe->SCSI filter for a SNT or USB 'type'.
virtual const char * get_usb_dev_type_by_id(int vendor_id, int product_id, int version=-1)
Get type name for USB device with known VENDOR:PRODUCT ID.
static smart_interface * s_instance
Pointer to the interface object.
virtual ata_device * get_jmb39x_device(const char *type, smart_device *smartdev)
Return JMB93x->ATA filter.
virtual ata_device * get_sat_device(const char *type, scsi_device *scsidev)
Return ATA->SCSI filter for a SAT or USB 'type'.
virtual std::string get_unique_dev_name(const char *name, const char *type) const
Return unique device name which is (only) suitable for duplicate detection.
virtual smart_device * get_smart_device(const char *name, const char *type)
Return device object for device 'name' with some 'type'.
smart_device::error_info m_err
virtual ata_device * get_ata_device(const char *name, const char *type)=0
Return standard ATA device.
const char * get_errmsg() const
Get last error message.
virtual ata_device * get_intelliprop_device(const char *type, ata_device *atadev)
Return filter for Intelliprop controllers.
static void init()
Initialize platform interface and register with smi().
bool decltype(nullptr) set_err_np(int no, const char *msg,...) __attribute_format_printf(3
Set last error number and message.
int get_errno() const
Get last error number.
virtual smart_device * get_custom_smart_device(const char *name, const char *type)
Return device for platform specific 'type'.
virtual std::string get_os_version_str()
Return info string about build host and/or OS version.
virtual std::string get_valid_custom_dev_types_str()
Return valid 'type' args accepted by above.
const smart_device::error_info & get_err() const
Get last error info struct.
void operator=(const smart_interface &)
virtual bool disable_system_auto_standby(bool disable)
Disable/Enable system auto standby/sleep mode.
virtual bool scan_smart_devices(smart_device_list &devlist, const char *type, const char *pattern=0)
Fill 'devlist' with devices of some 'type' with device names specified by some optional 'pattern'.
virtual smart_device * autodetect_smart_device(const char *name)=0
Autodetect device if no device type specified.
virtual std::string get_valid_dev_types_str()
Return valid args for device type option/directive.
virtual scsi_device * get_scsi_device(const char *name, const char *type)=0
Return standard SCSI device.
friend smart_interface * smi()
Global access to the (usually singleton) smart_interface.
virtual smart_device * get_scsi_passthrough_device(const char *type, scsi_device *scsidev)
Return ATA->SCSI of NVMe->SCSI filter for a SAT, SNT or USB 'type'.
virtual nvme_device * get_nvme_device(const char *name, const char *type, unsigned nsid)
Return standard NVMe device.
virtual ~smart_interface()
virtual ata_device * autodetect_sat_device(scsi_device *scsidev, const unsigned char *inqdata, unsigned inqsize)
Try to detect a SAT device behind a SCSI interface.
bool set_err_var(smart_device::error_info *err, int no)
Set last error number and default message to any error_info.
bool set_err(int no, const char *msg,...) __attribute_format_printf(3
Set last error number and message.
virtual bool is_raid_dev_type(const char *type) const
Return true if the 'type' string contains a RAID drive number.
any_device_auto_ptr< scsi_device > scsi_device_auto_ptr
std::vector< std::string > smart_devtype_list
List of types for DEVICESCAN.
any_device_auto_ptr< smart_device > smart_device_auto_ptr
any_device_auto_ptr< nvme_device > nvme_device_auto_ptr
smart_interface * smi()
Global access to the (usually singleton) smart_interface.
any_device_auto_ptr< ata_device > ata_device_auto_ptr
ATA pass through input parameters.
enum ata_cmd_in::@29 direction
I/O direction.
void set_data_out(const void *buf, unsigned nsectors)
Prepare for 28-bit DATA OUT command.
void * buffer
Pointer to data buffer.
void set_data_in_48bit(void *buf, unsigned nsectors)
Prepare for 48-bit DATA IN command.
ata_in_regs_48bit in_regs
Input registers.
unsigned size
Size of buffer.
ata_out_regs_flags out_needed
True if output register value needed.
void set_data_in(void *buf, unsigned nsectors)
Prepare for 28-bit DATA IN command.
ATA pass through output parameters.
ata_out_regs_48bit out_regs
Output registers.
ATA Input registers for 48-bit commands.
bool is_48bit_cmd() const
Return true if 48-bit command.
ata_reg_alias_16 lba_high_16
ata_reg_alias_16 sector_count_16
bool is_real_48bit_cmd() const
Return true if 48-bit command with any nonzero high byte.
ata_reg_alias_16 features_16
ata_in_regs prev
"previous content"
ata_reg_alias_16 lba_low_16
ata_reg_alias_16 lba_mid_16
ATA Input registers (for 28-bit commands)
bool is_set() const
Return true if any register is set.
ata_register sector_count
ATA Output registers for 48-bit commands.
ata_out_regs prev
read with HOB=1
ata_reg_alias_16 lba_mid_16
ata_reg_alias_16 sector_count_16
ata_reg_alias_16 lba_low_16
ata_reg_alias_16 lba_high_16
Flags for each ATA output register.
ata_out_regs_flags()
Default constructor clears all flags.
bool is_set() const
Return true if any flag is set.
ATA Output registers (for 28-bit commands)
ata_register sector_count
bool is_set() const
Return true if any register is set.
NVMe pass through input parameters.
unsigned char direction() const
Get I/O direction from opcode.
unsigned char opcode
Opcode (CDW0 07:00)
unsigned size
Size of buffer.
unsigned cdw15
Cmd specific.
unsigned nsid
Namespace ID.
void set_data_in(unsigned char op, void *buf, unsigned sz)
void * buffer
Pointer to data buffer.
NVMe pass through output parameters.
bool status_valid
true if status is valid
unsigned short status
Status Field (DW3 31:17)
unsigned result
Command specific result (DW0)
std::string req_type
Device type requested by user, empty if none.
std::string info_name
Informal name.
device_info(const char *d_name, const char *d_type, const char *r_type)
std::string dev_type
Actual device type.
std::string dev_name
Device (path)name.
Error (number,message) pair.
std::string msg
Error message.
error_info(int n, const char *m)
#define __attribute_format_printf(x, y)