30 #if defined(HAVE_GETTIMEOFDAY)
32 #elif defined(HAVE_FTIME)
33 #include <sys/timeb.h>
45 const char * dev_type,
const char * req_type)
46 : m_intf(intf), m_info(dev_name, dev_type, req_type),
47 m_ata_ptr(0), m_scsi_ptr(0), m_nvme_ptr(0)
53 : m_intf(0), m_ata_ptr(0), m_scsi_ptr(0), m_nvme_ptr(0)
55 throw std::logic_error(
"smart_device: wrong constructor called in implementation class");
79 va_list ap; va_start(ap, msg);
115 : features_16(features, prev.features),
116 sector_count_16(sector_count, prev.sector_count),
117 lba_low_16(lba_low, prev.lba_low),
118 lba_mid_16(lba_mid, prev.lba_mid),
119 lba_high_16(lba_high, prev.lba_high),
120 lba_48( lba_low, lba_mid, lba_high,
121 prev.lba_low, prev.lba_mid, prev.lba_high)
126 : sector_count_16(sector_count, prev.sector_count),
127 lba_low_16(lba_low, prev.lba_low),
128 lba_mid_16(lba_mid, prev.lba_mid),
129 lba_high_16(lba_high, prev.lba_high),
130 lba_48( lba_low, lba_mid, lba_high,
131 prev.lba_low, prev.lba_mid, prev.lba_high)
136 : direction(no_data),
153 unsigned flags,
const char * type )
167 return set_err(EINVAL,
"Buffer size %u > 0 for NO DATA command", in.
size);
171 return set_err(EINVAL,
"Buffer not set for DATA IN/OUT command");
174 if (count * 512 != in.
size)
175 return set_err(EINVAL,
"Sector count %u does not match buffer size %u", count, in.
size);
179 const char * errmsg = 0;
181 errmsg =
"DATA OUT ATA commands not implemented";
186 errmsg =
"Read of ATA output registers not implemented";
188 errmsg =
"Multi-sector ATA commands not implemented";
190 errmsg =
"48-bit ATA commands not implemented";
192 errmsg =
"48-bit ATA commands not fully implemented";
195 return set_err(ENOSYS,
"%s%s%s%s", errmsg,
196 (type ?
" [" :
""), (type ? type :
""), (type ?
"]" :
""));
213 throw std::logic_error(
"nvme_device: set_nvme_err() called with status=0");
217 return set_err(EIO,
"%sNVMe Status 0x%02x", (msg ? msg :
""), status);
226 m_tunnel_base_dev(tunnel_dev)
278 return SMARTMONTOOLS_BUILD_HOST;
285 "ata, scsi, nvme[,NSID], sat[,auto][,N][+TYPE], usbcypress[,X], "
286 "usbjmicron[,p][,x][,N], usbprolific, usbsunplus, intelliprop,N[+TYPE]";
302 #if defined(HAVE_GETTIMEOFDAY)
303 #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
305 static bool have_clock_monotonic =
true;
306 if (have_clock_monotonic) {
308 if (!clock_gettime(CLOCK_MONOTONIC, &ts))
309 return ts.tv_sec * 1000000LL + ts.tv_nsec/1000;
310 have_clock_monotonic =
false;
316 gettimeofday(&tv, 0);
317 return tv.tv_sec * 1000000LL + tv.tv_usec;
319 #elif defined(HAVE_FTIME)
323 return tb.time * 1000000LL + tb.millitm * 1000;
340 va_list ap; va_start(ap, msg);
355 if (err->
msg.empty() && no != 0)
375 if (!type || !*type) {
378 set_err(EINVAL,
"Unable to detect device type");
387 if (!strcmp(type,
"ata"))
389 else if (!strcmp(type,
"scsi"))
393 int n1 = -1, n2 = -1, len = strlen(type);
395 sscanf(type,
"nvme%n,0x%x%n", &n1, &nsid, &n2);
396 if (!(n1 == len || n2 == len)) {
397 set_err(EINVAL,
"Invalid NVMe namespace id in '%s'", type);
403 else if ( ((!strncmp(type,
"sat", 3) && (!type[3] || strchr(
",+", type[3])))
404 || (!strncmp(type,
"usb", 3)))) {
406 unsigned satlen = strcspn(type,
"+");
407 std::string sattype(type, satlen);
408 const char * basetype = (type[satlen] ? type+satlen+1 :
"");
418 if (!basedev->is_scsi()) {
419 set_err(EINVAL,
"Type '%s+...': Device type '%s' is not SCSI", sattype.c_str(), basetype);
428 unsigned phydrive = ~0;
int n = -1;
char c = 0;
429 sscanf(type,
"intelliprop,%u%n%c", &phydrive, &n, &c);
430 if (!((n == (
int)strlen(type) || c ==
'+') && phydrive <= 3)) {
431 set_err(EINVAL,
"Option '-d intelliprop,N' requires N between 0 and 3");
434 const char * basetype = (type[n] ? type + n + 1 :
"");
444 if (!basedev->is_ata()) {
445 set_err(EINVAL,
"Type '%s': Device type '%s' is not ATA", type, basetype);
452 set_err(EINVAL,
"Unknown device type '%s'", type);
456 set_err(EINVAL,
"Not a device of type '%s'", type);
463 unsigned n = types.size();
469 for (
unsigned i = 0; i < n; i++) {
481 set_err(ENOSYS,
"NVMe devices are not supported in this version of smartmontools");
virtual int64_t get_timer_usec()
Get microseconds since some unspecified starting point.
Error (number,message) pair.
int get_errno() const
Get last error number.
virtual void release(const smart_device *dev)
Release ownership of other device.
ata_out_regs_flags out_needed
True if output register value needed.
const char * get_errmsg() const
Get last error message.
virtual std::string get_valid_dev_types_str()
Return valid args for device type option/directive.
std::string msg
Error message.
virtual ata_device * get_sat_device(const char *type, scsi_device *scsidev)
Return ATA->SCSI filter for a SAT or USB 'type'.
do_not_use_in_implementation_classes
Dummy enum for dummy constructor.
ata_in_regs prev
"previous content"
smart_device::error_info m_err
tunnelled_device_base(smart_device *tunnel_dev)
int get_errno() const
Get last error number.
virtual void release(const smart_device *dev)
Release ownership of other device.
virtual bool open()=0
Open device, return false on error.
bool str_starts_with(const char *str, const char *prefix)
void clear_err()
Clear last error info.
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.
Smart pointer class for device pointers.
virtual bool is_powered_down()
Early test if device is powered up or down.
virtual const char * get_msg_for_errno(int no)
Convert error number into message, used by set_err(no).
virtual std::string get_valid_custom_dev_types_str()
Return valid 'type' args accepted by above.
virtual bool close()=0
Close device, return false on error.
void * buffer
Pointer to data buffer.
NVMe pass through output parameters.
#define DEV_INTERFACE_H_CVSID
bool is_real_48bit_cmd() const
Return true if 48-bit command with any nonzero high byte.
virtual smart_device * get_smart_device(const char *name, const char *type)
Return device object for device 'name' with some 'type'.
bool ata_cmd_is_supported(const ata_cmd_in &in, unsigned flags, const char *type=0)
Check command input parameters.
ata_in_regs_48bit in_regs
Input registers.
virtual ata_device * get_ata_device(const char *name, const char *type)=0
Return standard ATA device.
List of devices for DEVICESCAN.
device_type * release()
Return the pointer and release ownership.
bool set_err_var(smart_device::error_info *err, int no)
Set last error number and default message to any error_info.
virtual bool is_open() const =0
Return true if device is open.
enum ata_cmd_in::@29 direction
I/O direction.
The platform interface abstraction.
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out)=0
ATA pass through.
std::vector< std::string > smart_devtype_list
List of types for DEVICESCAN.
bool status_valid
true if status is valid
static smart_interface * s_instance
Pointer to the interface object.
virtual bool open()
Open device, return false on error.
virtual smart_device * autodetect_smart_device(const char *name)=0
Autodetect device if no device type specified.
virtual nvme_device * get_nvme_device(const char *name, const char *type, unsigned nsid)
Return standard NVMe device.
virtual smart_device * get_custom_smart_device(const char *name, const char *type)
Return device for platform specific 'type'.
virtual std::string get_app_examples(const char *appname)
Return example string for program 'appname'.
bool set_err(int no, const char *msg,...) __attribute_format_printf(3
Set last error number and message.
bool is_set() const
Return true if any flag is set.
virtual bool owns(const smart_device *dev) const
Return true if other device is owned by this device.
unsigned size
Size of buffer.
virtual ~tunnelled_device_base()
std::string std::string vstrprintf(const char *fmt, va_list ap)
bool is_48bit_cmd() const
Return true if 48-bit command.
virtual bool scan_smart_devices(smart_device_list &devlist, const char *type, const char *pattern=0)=0
Fill 'devlist' with devices of some 'type' with device names specified by some optional 'pattern'...
Base class for all devices.
ata_register sector_count
virtual bool disable_system_auto_standby(bool disable)
Disable/Enable system auto standby/sleep mode.
smart_device * m_tunnel_base_dev
ata_device * get_intelliprop_device(smart_interface *intf, unsigned phydrive, ata_device *atadev)
virtual scsi_device * get_scsi_device(const char *name, const char *type)=0
Return standard SCSI device.
virtual bool close()
Close device, return false on error.
virtual smart_device * autodetect_open()
Open device with autodetection support.
ATA pass through input parameters.
std::string strprintf(const char *fmt,...)
const char * dev_interface_cpp_cvsid
void append(smart_device_list &devlist)
smart_interface * smi()
Get interface which produced this object.
const error_info & get_err() const
Get last error info struct.
unsigned short status
Status Field (DW3 31:17)
bool set_err(int no, const char *msg,...) __attribute_format_printf(3
Set last error number and message.
virtual bool is_open() const
Return true if device is open.
virtual bool ata_identify_is_cached() const
Return true if OS caches ATA identify sector.
virtual bool is_syscall_unsup() const
Return true if last error indicates an unsupported system call.
ATA pass through output parameters.
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 owns(const smart_device *dev) const
Return true if other device is owned by this device.
virtual std::string get_os_version_str()
Return info string about build host and/or OS version.