33 const char * dev_type,
const char * req_type)
34: m_intf(intf), m_info(dev_name, dev_type, req_type),
35 m_ata_ptr(0), m_scsi_ptr(0), m_nvme_ptr(0)
41: m_intf(0), m_ata_ptr(0), m_scsi_ptr(0), m_nvme_ptr(0)
43 throw std::logic_error(
"smart_device: wrong constructor called in implementation class");
67 va_list
ap; va_start(
ap, msg);
103: features_16(features, prev.features),
104 sector_count_16(sector_count, prev.sector_count),
105 lba_low_16(lba_low, prev.lba_low),
106 lba_mid_16(lba_mid, prev.lba_mid),
107 lba_high_16(lba_high, prev.lba_high),
108 lba_48( lba_low, lba_mid, lba_high,
109 prev.lba_low, prev.lba_mid, prev.lba_high)
114: sector_count_16(sector_count, prev.sector_count),
115 lba_low_16(lba_low, prev.lba_low),
116 lba_mid_16(lba_mid, prev.lba_mid),
117 lba_high_16(lba_high, prev.lba_high),
118 lba_48( lba_low, lba_mid, lba_high,
119 prev.lba_low, prev.lba_mid, prev.lba_high)
141 unsigned flags,
const char * type )
155 return set_err(EINVAL,
"Buffer size %u > 0 for NO DATA command", in.
size);
159 return set_err(EINVAL,
"Buffer not set for DATA IN/OUT command");
163 return set_err(EINVAL,
"Sector count %u does not match buffer size %u",
count, in.
size);
167 const char * errmsg = 0;
169 errmsg =
"DATA OUT ATA commands not implemented";
174 errmsg =
"Read of ATA output registers not implemented";
176 errmsg =
"Multi-sector ATA commands not implemented";
178 errmsg =
"48-bit ATA commands not implemented";
180 errmsg =
"48-bit ATA commands not fully implemented";
183 return set_err(ENOSYS,
"%s%s%s%s", errmsg,
184 (type ?
" [" :
""), (type ? type :
""), (type ?
"]" :
""));
201 unsigned char sense[32] = {0, };
209 pout(
"%sscsi_pass_through() failed, errno=%d [%s]\n",
233 throw std::logic_error(
"nvme_device: set_nvme_err() called with status=0");
237 return set_err(EIO,
"%sNVMe Status 0x%02x", (msg ? msg :
""), status);
246 m_tunnel_base_dev(tunnel_dev)
298 return SMARTMONTOOLS_BUILD_HOST;
305 "ata, scsi[+TYPE], nvme[,NSID], sat[,auto][,N][+TYPE], usbasm1352r,N, usbcypress[,X], "
306 "usbjmicron[,p][,x][,N], usbprolific, usbsunplus, sntasmedia, sntjmicron[,NSID], "
307 "sntrealtek, jmb39x[-q],N[,sLBA][,force][+TYPE], "
308 "jms56x,N[,sLBA][,force][+TYPE]";
332 va_list
ap; va_start(
ap, msg);
345 va_list
ap; va_start(
ap, msg);
360 if (err->
msg.empty() && no != 0)
372 std::string unique_name;
373#if defined(HAVE_UNISTD_H) && !defined(_WIN32) && !defined(__OS2__)
374 char * p = realpath(name, (
char *)0);
385 unique_name +=
" ["; unique_name += type; unique_name +=
']';
392 if (!strchr(type,
','))
397 if (sscanf(type,
"%*[^,],%d", &i) != 1)
412 if (!type || !*type) {
415 set_err(EINVAL,
"Unable to detect device type");
424 if (!strcmp(type,
"ata"))
426 else if (!strcmp(type,
"scsi"))
430 int n1 = -1, n2 = -1, len = strlen(type);
432 sscanf(type,
"nvme%n,0x%x%n", &n1, &
nsid, &n2);
433 if (!(n1 == len || n2 == len))
434 return set_err_np(EINVAL,
"Invalid NVMe namespace id in '%s'", type);
438 else if ( (
str_starts_with(type,
"sat") && (!type[3] || strchr(
",+", type[3])))
442 unsigned satlen = strcspn(type,
"+");
443 std::string sattype(type, satlen);
444 const char * basetype = (type[satlen] ? type+satlen+1 :
"");
452 if (!basedev->is_scsi())
453 return set_err_np(EINVAL,
"Type '%s+...': Device type '%s' is not SCSI", sattype.c_str(), basetype);
468 unsigned jmblen = strcspn(type,
"+");
469 std::string jmbtype(type, jmblen);
470 const char * basetype = (type[jmblen] ? type+jmblen+1 :
"");
483 unsigned itllen = strcspn(type,
"+");
484 std::string itltype(type, itllen);
485 const char * basetype = (type[itllen] ? type+itllen+1 :
"");
493 if (!basedev->is_ata())
494 return set_err_np(EINVAL,
"Type '%s': Device type '%s' is not ATA", type, basetype);
499 return set_err_np(EINVAL,
"Unknown device type '%s'", type);
502 set_err(EINVAL,
"Not a device of type '%s'", type);
507 const char * ,
const char * )
515 unsigned n = types.size();
521 for (
unsigned i = 0; i < n; i++) {
533 return set_err_np(ENOSYS,
"NVMe devices are not supported in this version of smartmontools");
548 if (!strncmp(type,
"snt", 3)) {
Smart pointer class for device pointers.
device_type * release()
Return the pointer and release ownership.
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.
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out)=0
ATA 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.
bool scsi_pass_through_and_check(scsi_cmnd_io *iop, const char *msg="")
virtual bool scsi_pass_through(scsi_cmnd_io *iop)=0
SCSI pass through.
List of devices for DEVICESCAN.
void append(smart_device_list &devlist)
Base class for all devices.
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.
virtual bool is_powered_down()
Early test if device is powered up or down.
smart_interface * smi()
Get interface which produced this object.
const char * get_errmsg() const
Get last error message.
virtual bool close()=0
Close device, return false on error.
bool set_err(int no, const char *msg,...) __attribute_format_printf(3
Set last error number and message.
do_not_use_in_implementation_classes
Dummy enum for dummy constructor.
virtual smart_device * autodetect_open()
Open device with autodetection support.
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.
smart_device(smart_interface *intf, const char *dev_name, const char *dev_type, const char *req_type)
Constructor to init interface and device info.
virtual bool open()=0
Open device, return false on error.
The platform interface abstraction.
virtual std::string get_app_examples(const char *appname)
Return example string for program 'appname'.
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'.
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.
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.
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.
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.
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.
virtual bool open() override
Open device, return false on error.
virtual bool owns(const smart_device *dev) const override
Return true if other device is owned by this device.
virtual void release(const smart_device *dev) override
Release ownership of other device.
smart_device * m_tunnel_base_dev
virtual ~tunnelled_device_base()
virtual bool is_open() const override
Return true if device is open.
virtual bool close() override
Close device, return false on error.
tunnelled_device_base(smart_device *tunnel_dev)
const char * dev_interface_cpp_cvsid
#define DEV_INTERFACE_H_CVSID
std::vector< std::string > smart_devtype_list
List of types for DEVICESCAN.
int scsiSimpleSenseFilter(const struct scsi_sense_disect *sinfo)
void scsi_do_sense_disect(const struct scsi_cmnd_io *io_buf, struct scsi_sense_disect *out)
const char * scsiErrString(int scsiErr)
unsigned char scsi_debugmode
#define SCSI_TIMEOUT_DEFAULT
const char const char va_list ap
void pout(const char *fmt,...)
ATA pass through input parameters.
enum ata_cmd_in::@29 direction
I/O direction.
void * buffer
Pointer to data buffer.
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.
ATA pass through output parameters.
bool is_48bit_cmd() const
Return true if 48-bit command.
bool is_real_48bit_cmd() const
Return true if 48-bit command with any nonzero high byte.
ata_in_regs prev
"previous content"
ata_register sector_count
bool is_set() const
Return true if any flag is set.
NVMe pass through output parameters.
bool status_valid
true if status is valid
unsigned short status
Status Field (DW3 31:17)
Error (number,message) pair.
std::string msg
Error message.
std::string strprintf(const char *fmt,...)
std::string std::string vstrprintf(const char *fmt, va_list ap)
bool str_starts_with(const char *str, const char *prefix)