34 const char * dev_type,
const char * req_type)
35: m_intf(intf), m_info(dev_name, dev_type, req_type),
36 m_ata_ptr(0), m_scsi_ptr(0), m_nvme_ptr(0)
42: m_intf(0), m_ata_ptr(0), m_scsi_ptr(0), m_nvme_ptr(0)
44 throw std::logic_error(
"smart_device: wrong constructor called in implementation class");
68 va_list
ap; va_start(
ap, msg);
104: features_16(features, prev.features),
105 sector_count_16(sector_count, prev.sector_count),
106 lba_low_16(lba_low, prev.lba_low),
107 lba_mid_16(lba_mid, prev.lba_mid),
108 lba_high_16(lba_high, prev.lba_high),
109 lba_48( lba_low, lba_mid, lba_high,
110 prev.lba_low, prev.lba_mid, prev.lba_high)
115: sector_count_16(sector_count, prev.sector_count),
116 lba_low_16(lba_low, prev.lba_low),
117 lba_mid_16(lba_mid, prev.lba_mid),
118 lba_high_16(lba_high, prev.lba_high),
119 lba_48( lba_low, lba_mid, lba_high,
120 prev.lba_low, prev.lba_mid, prev.lba_high)
142 unsigned flags,
const char * type )
156 return set_err(EINVAL,
"Buffer size %u > 0 for NO DATA command", in.
size);
160 return set_err(EINVAL,
"Buffer not set for DATA IN/OUT command");
164 return set_err(EINVAL,
"Sector count %u does not match buffer size %u",
count, in.
size);
168 const char * errmsg = 0;
170 errmsg =
"DATA OUT ATA commands not implemented";
175 errmsg =
"Read of ATA output registers not implemented";
177 errmsg =
"Multi-sector ATA commands not implemented";
179 errmsg =
"48-bit ATA commands not implemented";
181 errmsg =
"48-bit ATA commands not fully implemented";
184 return set_err(ENOSYS,
"%s%s%s%s", errmsg,
185 (type ?
" [" :
""), (type ? type :
""), (type ?
"]" :
""));
202 unsigned char sense[32] = {0, };
210 pout(
"%sscsi_pass_through() failed, errno=%d [%s]\n",
248 m_tunnel_base_dev(tunnel_dev)
300 return SMARTMONTOOLS_BUILD_HOST;
307 "ata, scsi[+TYPE], nvme[,NSID], sat[,auto][,N][+TYPE], usbasm1352r,N, usbcypress[,X], "
308 "usbjmicron[,p][,x][,N], usbprolific, usbsunplus, sntasmedia, sntjmicron[,NSID], "
309 "sntrealtek, jmb39x[-q],N[,sLBA][,force][+TYPE], "
310 "jms56x,N[,sLBA][,force][+TYPE]";
334 va_list
ap; va_start(
ap, msg);
347 va_list
ap; va_start(
ap, msg);
362 if (err->
msg.empty() && no != 0)
374 std::string unique_name;
375#if defined(HAVE_UNISTD_H) && !defined(_WIN32) && !defined(__OS2__)
376 char * p = realpath(name, (
char *)0);
387 unique_name +=
" ["; unique_name += type; unique_name +=
']';
394 if (!strchr(type,
','))
399 if (sscanf(type,
"%*[^,],%d", &i) != 1)
414 if (!type || !*type) {
417 set_err(EINVAL,
"Unable to detect device type");
426 if (!strcmp(type,
"ata"))
428 else if (!strcmp(type,
"scsi"))
432 int n1 = -1, n2 = -1, len = strlen(type);
434 sscanf(type,
"nvme%n,0x%x%n", &n1, &
nsid, &n2);
435 if (!(n1 == len || n2 == len))
436 return set_err_np(EINVAL,
"Invalid NVMe namespace id in '%s'", type);
440 else if ( (
str_starts_with(type,
"sat") && (!type[3] || strchr(
",+", type[3])))
444 unsigned satlen = strcspn(type,
"+");
445 std::string sattype(type, satlen);
446 const char * basetype = (type[satlen] ? type+satlen+1 :
"");
454 if (!basedev->is_scsi())
455 return set_err_np(EINVAL,
"Type '%s+...': Device type '%s' is not SCSI", sattype.c_str(), basetype);
470 unsigned jmblen = strcspn(type,
"+");
471 std::string jmbtype(type, jmblen);
472 const char * basetype = (type[jmblen] ? type+jmblen+1 :
"");
485 unsigned itllen = strcspn(type,
"+");
486 std::string itltype(type, itllen);
487 const char * basetype = (type[itllen] ? type+itllen+1 :
"");
495 if (!basedev->is_ata())
496 return set_err_np(EINVAL,
"Type '%s': Device type '%s' is not ATA", type, basetype);
501 return set_err_np(EINVAL,
"Unknown device type '%s'", type);
504 set_err(EINVAL,
"Not a device of type '%s'", type);
509 const char * ,
const char * )
517 unsigned n = types.size();
523 for (
unsigned i = 0; i < n; i++) {
535 return set_err_np(ENOSYS,
"NVMe devices are not supported in this version of smartmontools");
550 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 nvme_status_to_errno(uint16_t status)
const char * nvme_status_to_info_str(char *buf, size_t bufsize, uint16_t status)
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)