smartmontools  SVN Rev 4814
Utility to control and monitor storage systems with "S.M.A.R.T."
dev_interface.h
Go to the documentation of this file.
1 /*
2  * dev_interface.h
3  *
4  * Home page of code is: http://www.smartmontools.org
5  *
6  * Copyright (C) 2008-16 Christian Franke
7  *
8  * SPDX-License-Identifier: GPL-2.0-or-later
9  */
10 
11 #ifndef DEV_INTERFACE_H
12 #define DEV_INTERFACE_H
13 
14 #define DEV_INTERFACE_H_CVSID "$Id: dev_interface.h 4760 2018-08-19 18:45:53Z chrfranke $\n"
15 
16 #include "utility.h"
17 
18 #include <stdexcept>
19 #include <string>
20 #include <vector>
21 
22 /////////////////////////////////////////////////////////////////////////////
23 // Common functionality for all device types
24 
25 // Forward declarations
26 class smart_interface;
27 class ata_device;
28 class scsi_device;
29 class nvme_device;
30 
31 /// Base class for all devices
33 {
34 // Types
35 public:
36  /// Device info strings
37  struct device_info {
39  { }
40  device_info(const char * d_name, const char * d_type, const char * r_type)
41  : dev_name(d_name), info_name(d_name),
42  dev_type(d_type), req_type(r_type)
43  { }
44 
45  std::string dev_name; ///< Device (path)name
46  std::string info_name; ///< Informal name
47  std::string dev_type; ///< Actual device type
48  std::string req_type; ///< Device type requested by user, empty if none
49  };
50 
51  /// Error (number,message) pair
52  struct error_info {
53  explicit error_info(int n = 0)
54  : no(n) { }
55  error_info(int n, const char * m)
56  : no(n), msg(m) { }
57  void clear()
58  { no = 0; msg.erase(); }
59 
60  int no; ///< Error number
61  std::string msg; ///< Error message
62  };
63 
64 // Construction
65 protected:
66  /// Constructor to init interface and device info.
67  /// Must be called in implementation classes.
68  smart_device(smart_interface * intf, const char * dev_name,
69  const char * dev_type, const char * req_type);
70 
71  /// Dummy enum for dummy constructor.
73  /// Dummy constructor for abstract classes.
74  /// Must never be called in implementation classes.
76 
77 public:
78  virtual ~smart_device() throw();
79 
80 // Attributes
81 public:
82  ///////////////////////////////////////////////
83  // Dynamic downcasts to actual device flavor
84 
85  /// Return true if ATA device
86  bool is_ata() const
87  { return !!m_ata_ptr; }
88  /// Return true if SCSI device
89  bool is_scsi() const
90  { return !!m_scsi_ptr; }
91  /// Return true if NVMe device
92  bool is_nvme() const
93  { return !!m_nvme_ptr; }
94 
95  /// Downcast to ATA device.
97  { return m_ata_ptr; }
98  /// Downcast to ATA device (const).
99  const ata_device * to_ata() const
100  { return m_ata_ptr; }
101  /// Downcast to SCSI device.
103  { return m_scsi_ptr; }
104  /// Downcast to SCSI device (const).
105  const scsi_device * to_scsi() const
106  { return m_scsi_ptr; }
107  /// Downcast to NVMe device.
109  { return m_nvme_ptr; }
110  /// Downcast to NVMe device (const).
111  const nvme_device * to_nvme() const
112  { return m_nvme_ptr; }
113 
114  ///////////////////////////////////////////////
115  // Device information
116 
117  /// Get device info struct.
118  const device_info & get_info() const
119  { return m_info; }
120 
121  /// Get device (path)name.
122  const char * get_dev_name() const
123  { return m_info.dev_name.c_str(); }
124  /// Get informal name.
125  const char * get_info_name() const
126  { return m_info.info_name.c_str(); }
127  /// Get device type.
128  const char * get_dev_type() const
129  { return m_info.dev_type.c_str(); }
130  /// Get type requested by user, empty if none.
131  const char * get_req_type() const
132  { return m_info.req_type.c_str(); }
133 
134 protected:
135  /// R/W access to device info struct.
137  { return m_info; }
138 
139 public:
140  ///////////////////////////////////////////////
141  // Last error information
142 
143  /// Get last error info struct.
144  const error_info & get_err() const
145  { return m_err; }
146  /// Get last error number.
147  int get_errno() const
148  { return m_err.no; }
149  /// Get last error message.
150  const char * get_errmsg() const
151  { return m_err.msg.c_str(); }
152 
153  /// Return true if last error indicates an unsupported system call.
154  /// Default implementation returns true on ENOSYS and ENOTSUP.
155  virtual bool is_syscall_unsup() const;
156 
157  /// Set last error number and message.
158  /// Printf()-like formatting is supported.
159  /// Returns false always to allow use as a return expression.
160  bool set_err(int no, const char * msg, ...)
162 
163  /// Set last error info struct.
164  bool set_err(const error_info & err)
165  { m_err = err; return false; }
166 
167  /// Clear last error info.
168  void clear_err()
169  { m_err.clear(); }
170 
171  /// Set last error number and default message.
172  /// Message is retrieved from interface's get_msg_for_errno(no).
173  bool set_err(int no);
174 
175  /// Get current number of allocated 'smart_device' objects.
176  static int get_num_objects()
177  { return s_num_objects; }
178 
179 // Operations
180 public:
181  ///////////////////////////////////////////////
182  // Device open/close
183  // Must be implemented in derived class
184 
185  /// Return true if device is open.
186  virtual bool is_open() const = 0;
187 
188  /// Open device, return false on error.
189  virtual bool open() = 0;
190 
191  /// Close device, return false on error.
192  virtual bool close() = 0;
193 
194  /// Open device with autodetection support.
195  /// May return another device for further access.
196  /// In this case, the original pointer is no longer valid.
197  /// Default implementation calls 'open()' and returns 'this'.
198  virtual smart_device * autodetect_open();
199 
200  ///////////////////////////////////////////////
201  // Support for checking power mode reported by operating system
202 
203  /// Early test if device is powered up or down.
204  /// Can be used without calling 'open()' first!
205  /// Return true when device is powered down, false when
206  /// powered up. If this function is not implemented or
207  /// the mode cannot be determined, return false.
208  /// Default implementation returns false.
209  virtual bool is_powered_down();
210 
211  ///////////////////////////////////////////////
212  // Support for tunnelled devices
213 
214  /// Return true if other device is owned by this device.
215  /// Default implementation returns false.
216  virtual bool owns(const smart_device * dev) const;
217 
218  /// Release ownership of other device.
219  /// Default implementation does nothing.
220  virtual void release(const smart_device * dev);
221 
222 protected:
223  /// Get interface which produced this object.
225  { return m_intf; }
226  /// Get interface which produced this object (const).
227  const smart_interface * smi() const
228  { return m_intf; }
229 
230 // Implementation
231 private:
235 
236  // Pointers for to_ata(), to_scsi(), to_nvme()
237  // set by ATA/SCSI/NVMe interface classes.
238  friend class ata_device;
240  friend class scsi_device;
242  friend class nvme_device;
244 
245  // Number of objects.
246  static int s_num_objects;
247 
248  // Prevent copy/assigment
249  smart_device(const smart_device &);
250  void operator=(const smart_device &);
251 };
252 
253 
254 /////////////////////////////////////////////////////////////////////////////
255 // ATA specific interface
256 
257 /// ATA register value and info whether it has ever been set
258 // (Automatically set by first assignment)
260 {
261 public:
263  : m_val(0x00), m_is_set(false) { }
264 
265  ata_register & operator=(unsigned char x)
266  { m_val = x; m_is_set = true; return * this; }
267 
268  unsigned char val() const
269  { return m_val; }
270  operator unsigned char() const
271  { return m_val; }
272 
273  bool is_set() const
274  { return m_is_set; }
275 
276 private:
277  unsigned char m_val; ///< Register value
278  bool m_is_set; ///< true if set
279 };
280 
281 /// ATA Input registers (for 28-bit commands)
283 {
284  // ATA-6/7 register names // ATA-3/4/5 // ATA-8
285  ata_register features; // features // features
286  ata_register sector_count; // sector count // count
287  ata_register lba_low; // sector number // ]
288  ata_register lba_mid; // cylinder low // ] lba
289  ata_register lba_high; // cylinder high // ]
290  ata_register device; // device/head // device
291  ata_register command; // command // command
292 
293  /// Return true if any register is set
294  bool is_set() const
295  { return (features.is_set() || sector_count.is_set()
296  || lba_low.is_set() || lba_mid.is_set() || lba_high.is_set()
297  || device.is_set() || command.is_set()); }
298 };
299 
300 /// ATA Output registers (for 28-bit commands)
302 {
310 
311  /// Return true if any register is set
312  bool is_set() const
313  { return (error.is_set() || sector_count.is_set()
314  || lba_low.is_set() || lba_mid.is_set() || lba_high.is_set()
315  || device.is_set() || status.is_set()); }
316 };
317 
318 
319 /// 16-bit alias to a 8-bit ATA register pair.
321 {
322 public:
324  : m_lo(lo), m_hi(hi) { }
325 
326  ata_reg_alias_16 & operator=(unsigned short x)
327  { m_lo = (unsigned char) x;
328  m_hi = (unsigned char)(x >> 8);
329  return * this; }
330 
331  unsigned short val() const
332  { return m_lo | (m_hi << 8); }
333  operator unsigned short() const
334  { return m_lo | (m_hi << 8); }
335 
336 private:
338 
339  // References must not be copied.
341  void operator=(const ata_reg_alias_16 &);
342 };
343 
344 
345 /// 48-bit alias to six 8-bit ATA registers (for LBA).
347 {
348 public:
350  ata_register & hl, ata_register & hm, ata_register & hh)
351  : m_ll(ll), m_lm(lm), m_lh(lh),
352  m_hl(hl), m_hm(hm), m_hh(hh)
353  { }
354 
356  {
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);
363  return * this;
364  }
365 
366  uint64_t val() const
367  {
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));
374  }
375 
376  operator uint64_t() const
377  { return val(); }
378 
379 private:
381  & m_hl, & m_hm, & m_hh;
382 
383  // References must not be copied.
385  void operator=(const ata_reg_alias_48 &);
386 };
387 
388 
389 /// ATA Input registers for 48-bit commands
390 // See section 4.14 of T13/1532D Volume 1 Revision 4b
391 //
392 // Uses ATA-6/7 method to specify 16-bit registers as
393 // recent (low byte) and previous (high byte) content of
394 // 8-bit registers.
395 //
396 // (ATA-8 ACS does not longer follow this scheme, it uses
397 // abstract registers with sufficient size and leaves the
398 // actual mapping to the transport layer.)
399 //
401 : public ata_in_regs // "most recently written" registers
402 {
403  ata_in_regs prev; ///< "previous content"
404 
405  // 16-bit aliases for above pair.
411 
412  // 48-bit alias to all 8-bit LBA registers.
414 
415  /// Return true if 48-bit command
416  bool is_48bit_cmd() const
417  { return prev.is_set(); }
418 
419  /// Return true if 48-bit command with any nonzero high byte
420  bool is_real_48bit_cmd() const
421  { return ( prev.features || prev.sector_count
422  || prev.lba_low || prev.lba_mid || prev.lba_high); }
423 
425 };
426 
427 
428 /// ATA Output registers for 48-bit commands
430 : public ata_out_regs // read with HOB=0
431 {
432  ata_out_regs prev; ///< read with HOB=1
433 
434  // 16-bit aliases for above pair.
439 
440  // 48-bit alias to all 8-bit LBA registers.
442 
444 };
445 
446 
447 /// Flags for each ATA output register
449 {
451 
452  /// Return true if any flag is set.
453  bool is_set() const
454  { return ( error || sector_count || lba_low
455  || lba_mid || lba_high || device || status); }
456 
457  /// Default constructor clears all flags.
459  : error(false), sector_count(false), lba_low(false), lba_mid(false),
460  lba_high(false), device(false), status(false) { }
461 };
462 
463 
464 /// ATA pass through input parameters
466 {
467  ata_in_regs_48bit in_regs; ///< Input registers
468  ata_out_regs_flags out_needed; ///< True if output register value needed
469  enum { no_data = 0, data_in, data_out } direction; ///< I/O direction
470  void * buffer; ///< Pointer to data buffer
471  unsigned size; ///< Size of buffer
472 
473  /// Prepare for 28-bit DATA IN command
474  void set_data_in(void * buf, unsigned nsectors)
475  {
476  buffer = buf;
477  in_regs.sector_count = nsectors;
478  direction = data_in;
479  size = nsectors * 512;
480  }
481 
482  /// Prepare for 28-bit DATA OUT command
483  void set_data_out(const void * buf, unsigned nsectors)
484  {
485  buffer = const_cast<void *>(buf);
486  in_regs.sector_count = nsectors;
488  size = nsectors * 512;
489  }
490 
491  /// Prepare for 48-bit DATA IN command
492  void set_data_in_48bit(void * buf, unsigned nsectors)
493  {
494  buffer = buf;
495  // Note: This also sets 'in_regs.is_48bit_cmd()'
496  in_regs.sector_count_16 = nsectors;
497  direction = data_in;
498  size = nsectors * 512;
499  }
500 
501  ata_cmd_in();
502 };
503 
504 /// ATA pass through output parameters
506 {
507  ata_out_regs_48bit out_regs; ///< Output registers
508 
509  ata_cmd_out();
510 };
511 
512 /// ATA device access
514 : virtual public /*extends*/ smart_device
515 {
516 public:
517  /// ATA pass through.
518  /// Return false on error.
519  /// Must be implemented in derived class.
520  virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out) = 0;
521 
522  /// ATA pass through without output registers.
523  /// Return false on error.
524  /// Calls ata_pass_through(in, dummy), cannot be reimplemented.
525  bool ata_pass_through(const ata_cmd_in & in);
526 
527  /// Return true if OS caches ATA identify sector.
528  /// Default implementation returns false.
529  virtual bool ata_identify_is_cached() const;
530 
531 protected:
532  /// Flags for ata_cmd_is_supported().
533  enum {
534  supports_data_out = 0x01, // PIO DATA OUT
535  supports_smart_status = 0x02, // read output registers for SMART STATUS only
536  supports_output_regs = 0x04, // read output registers for all commands
537  supports_multi_sector = 0x08, // more than one sector (1 DRQ/sector variant)
538  supports_48bit_hi_null = 0x10, // 48-bit commands with null high bytes only
539  supports_48bit = 0x20, // all 48-bit commands
540  };
541 
542  /// Check command input parameters.
543  /// Return false if required features are not implemented.
544  /// Calls set_err(...) accordingly.
545  bool ata_cmd_is_supported(const ata_cmd_in & in, unsigned flags,
546  const char * type = 0);
547 
548  /// Check command input parameters (old version).
549  // TODO: Remove if no longer used.
550  bool ata_cmd_is_ok(const ata_cmd_in & in,
551  bool data_out_support = false,
552  bool multi_sector_support = false,
553  bool ata_48bit_support = false)
554  {
555  return ata_cmd_is_supported(in,
556  (data_out_support ? supports_data_out : 0) |
558  (multi_sector_support ? supports_multi_sector : 0) |
559  (ata_48bit_support ? supports_48bit : 0));
560  }
561 
562  /// Hide/unhide ATA interface.
563  void hide_ata(bool hide = true)
564  { m_ata_ptr = (!hide ? this : 0); }
565 
566  /// Default constructor, registers device as ATA.
569  { hide_ata(false); }
570 };
571 
572 
573 /////////////////////////////////////////////////////////////////////////////
574 // SCSI specific interface
575 
576 struct scsi_cmnd_io;
577 
578 /// SCSI device access
580 : virtual public /*extends*/ smart_device
581 {
582 public:
583  /// SCSI pass through.
584  /// Returns false on error.
585  virtual bool scsi_pass_through(scsi_cmnd_io * iop) = 0;
586 
587  /// Always try READ CAPACITY(10) (rcap10) first but once we know
588  /// rcap16 is needed, use it instead.
590  { rcap16_first = true; }
591 
592  bool use_rcap16() const
593  { return rcap16_first; }
594 
595 protected:
596  /// Hide/unhide SCSI interface.
597  void hide_scsi(bool hide = true)
598  { m_scsi_ptr = (!hide ? this : 0); }
599 
600  /// Default constructor, registers device as SCSI.
603  rcap16_first(false)
604  { hide_scsi(false); }
605 
606 private:
608 };
609 
610 
611 /////////////////////////////////////////////////////////////////////////////
612 // NVMe specific interface
613 
614 /// NVMe pass through input parameters
616 {
617  unsigned char opcode; ///< Opcode (CDW0 07:00)
618  unsigned nsid; ///< Namespace ID
619  unsigned cdw10, cdw11, cdw12, cdw13, cdw14, cdw15; ///< Cmd specific
620 
621  void * buffer; ///< Pointer to data buffer
622  unsigned size; ///< Size of buffer
623 
624  enum {
625  no_data = 0x0, data_out = 0x1, data_in = 0x2, data_io = 0x3
626  };
627 
628  /// Get I/O direction from opcode
629  unsigned char direction() const
630  { return (opcode & 0x3); }
631 
632  // Prepare for DATA IN command
633  void set_data_in(unsigned char op, void * buf, unsigned sz)
634  {
635  opcode = op;
636  if (direction() != data_in)
637  throw std::logic_error("invalid opcode for DATA IN");
638  buffer = buf;
639  size = sz;
640  }
641 
643  : opcode(0), nsid(0),
644  cdw10(0), cdw11(0), cdw12(0), cdw13(0), cdw14(0), cdw15(0),
645  buffer(0), size(0)
646  { }
647 };
648 
649 /// NVMe pass through output parameters
651 {
652  unsigned result; ///< Command specific result (DW0)
653  unsigned short status; ///< Status Field (DW3 31:17)
654  bool status_valid; ///< true if status is valid
655 
657  : result(0), status(0), status_valid(false)
658  { }
659 };
660 
661 /// NVMe device access
663 : virtual public /*extends*/ smart_device
664 {
665 public:
666  /// NVMe pass through.
667  /// Return false on error.
668  virtual bool nvme_pass_through(const nvme_cmd_in & in, nvme_cmd_out & out) = 0;
669 
670  /// Get namespace id.
671  unsigned get_nsid() const
672  { return m_nsid; }
673 
674 protected:
675  /// Hide/unhide NVMe interface.
676  void hide_nvme(bool hide = true)
677  { m_nvme_ptr = (!hide ? this : 0); }
678 
679  /// Constructor requires namespace ID, registers device as NVMe.
680  explicit nvme_device(unsigned nsid)
682  m_nsid(nsid)
683  { hide_nvme(false); }
684 
685  /// Set namespace id.
686  /// Should be called in open() function if get_nsid() returns 0.
687  void set_nsid(unsigned nsid)
688  { m_nsid = nsid; }
689 
690  /// Set last error number and message if pass-through returns NVMe error status.
691  /// Returns false always to allow use as a return expression.
692  bool set_nvme_err(nvme_cmd_out & out, unsigned status, const char * msg = 0);
693 
694 private:
695  unsigned m_nsid;
696 };
697 
698 
699 /////////////////////////////////////////////////////////////////////////////
700 /// Smart pointer class for device pointers
701 
702 template <class Dev>
704 {
705 public:
706  typedef Dev device_type;
707 
708  /// Construct from optional pointer to device
709  /// and optional pointer to base device.
710  explicit any_device_auto_ptr(device_type * dev = 0,
711  smart_device * base_dev = 0)
712  : m_dev(dev), m_base_dev(base_dev) { }
713 
714  /// Destructor deletes device object.
716  { reset(); }
717 
718  /// Assign a new pointer.
719  /// Throws if a pointer is already assigned.
720  void operator=(device_type * dev)
721  {
722  if (m_dev)
723  fail();
724  m_dev = dev;
725  }
726 
727  /// Delete device object and clear the pointer.
728  void reset()
729  {
730  if (m_dev) {
731  if (m_base_dev && m_dev->owns(m_base_dev))
732  m_dev->release(m_base_dev);
733  delete m_dev;
734  m_dev = 0;
735  }
736  }
737 
738  /// Return the pointer and release ownership.
739  device_type * release()
740  {
741  device_type * dev = m_dev;
742  m_dev = 0;
743  return dev;
744  }
745 
746  /// Replace the pointer.
747  /// Used to call dev->autodetect_open().
748  void replace(device_type * dev)
749  { m_dev = dev; }
750 
751  /// Return the pointer.
752  device_type * get() const
753  { return m_dev; }
754 
755  /// Pointer dereferencing.
756  device_type & operator*() const
757  { return *m_dev; }
758 
759  /// Pointer dereferencing.
760  device_type * operator->() const
761  { return m_dev; }
762 
763  /// For (ptr != 0) check.
764  operator bool() const
765  { return !!m_dev; }
766 
767  /// For (ptr == 0) check.
768  bool operator !() const
769  { return !m_dev; }
770 
771 private:
772  device_type * m_dev;
774 
775  void fail() const
776  { throw std::logic_error("any_device_auto_ptr: wrong usage"); }
777 
778  // Prevent copy/assignment
780  void operator=(const any_device_auto_ptr<Dev> &);
781 };
782 
787 
788 
789 /////////////////////////////////////////////////////////////////////////////
790 // smart_device_list
791 
792 /// List of devices for DEVICESCAN
794 {
795 // Construction
796 public:
798  { }
799 
801  {
802  for (unsigned i = 0; i < m_list.size(); i++)
803  delete m_list[i];
804  }
805 
806 // Attributes
807  unsigned size() const
808  { return m_list.size(); }
809 
810 // Operations
811  void clear()
812  {
813  for (unsigned i = 0; i < m_list.size(); i++)
814  delete m_list[i];
815  m_list.clear();
816  }
817 
818 
820  { m_list.push_back(dev); }
821 
823  {
824  m_list.push_back(dev.get());
825  dev.release();
826  }
827 
828  smart_device * at(unsigned i)
829  { return m_list.at(i); }
830 
831  const smart_device * at(unsigned i) const
832  { return m_list.at(i); }
833 
834  smart_device * release(unsigned i)
835  {
836  smart_device * dev = m_list.at(i);
837  m_list[i] = 0;
838  return dev;
839  }
840 
841  void append(smart_device_list & devlist)
842  {
843  for (unsigned i = 0; i < devlist.size(); i++) {
844  smart_device * dev = devlist.at(i);
845  if (!dev)
846  continue;
847  push_back(dev);
848  devlist.m_list.at(i) = 0;
849  }
850  }
851 
852 // Implementation
853 private:
854  std::vector<smart_device *> m_list;
855 
856  // Prevent copy/assigment
858  void operator=(const smart_device_list &);
859 };
860 
861 
862 /// List of types for DEVICESCAN
863 typedef std::vector<std::string> smart_devtype_list;
864 
865 
866 /////////////////////////////////////////////////////////////////////////////
867 // smart_interface
868 
869 /// The platform interface abstraction
871 {
872 public:
873  /// Initialize platform interface and register with smi().
874  /// Must be implemented by platform module and register interface with set()
875  static void init();
876 
878  { }
879 
880  virtual ~smart_interface() throw()
881  { }
882 
883  /// Return info string about build host and/or OS version.
884  /// Default implementation returns SMARTMONTOOLS_BUILD_HOST.
885  virtual std::string get_os_version_str();
886 
887  /// Return valid args for device type option/directive.
888  /// Default implementation returns "ata, scsi, sat, usb*..."
889  /// concatenated with result from get_valid_custom_dev_types_str().
890  virtual std::string get_valid_dev_types_str();
891 
892  /// Return example string for program 'appname'.
893  /// Default implementation returns empty string.
894  /// For the migration of print_smartctl_examples(),
895  /// function is allowed to print examples to stdout.
896  /// TODO: Remove this hack.
897  virtual std::string get_app_examples(const char * appname);
898 
899  /// Get microseconds since some unspecified starting point.
900  /// Used only for command duration measurements in debug outputs.
901  /// Returns -1 if unsupported.
902  /// Default implementation uses clock_gettime(), gettimeofday() or ftime().
903  virtual int64_t get_timer_usec();
904 
905  /// Disable/Enable system auto standby/sleep mode.
906  /// Return false if unsupported or if system is running
907  /// on battery.
908  /// Default implementation returns false.
909  virtual bool disable_system_auto_standby(bool disable);
910 
911 
912  ///////////////////////////////////////////////
913  // Last error information
914 
915  /// Get last error info struct.
917  { return m_err; }
918  /// Get last error number.
919  int get_errno() const
920  { return m_err.no; }
921  /// Get last error message.
922  const char * get_errmsg() const
923  { return m_err.msg.c_str(); }
924 
925  /// Set last error number and message.
926  /// Printf()-like formatting is supported.
927  /// Returns false always to allow use as a return expression.
928  bool set_err(int no, const char * msg, ...)
930 
931  /// Set last error info struct.
932  bool set_err(const smart_device::error_info & err)
933  { m_err = err; return false; }
934 
935  /// Clear last error info.
936  void clear_err()
937  { m_err.clear(); }
938 
939  /// Set last error number and default message.
940  /// Message is retrieved from get_msg_for_errno(no).
941  bool set_err(int no);
942 
943  /// Set last error number and default message to any error_info.
944  /// Used by set_err(no).
945  bool set_err_var(smart_device::error_info * err, int no);
946 
947  /// Convert error number into message, used by set_err(no).
948  /// Default implementation returns strerror(no).
949  virtual const char * get_msg_for_errno(int no);
950 
951  ///////////////////////////////////////////////////////////////////////////
952  // Device factory:
953 
954  /// Return device object for device 'name' with some 'type'.
955  /// 'type' is 0 if not specified by user.
956  /// Return 0 on error.
957  /// Default implementation selects between ata, scsi and custom device.
958  virtual smart_device * get_smart_device(const char * name, const char * type);
959 
960  /// Fill 'devlist' with devices of some 'type' with device names
961  /// specified by some optional 'pattern'.
962  /// Use platform specific default if 'type' is empty or 0.
963  /// Return false on error.
964  virtual bool scan_smart_devices(smart_device_list & devlist, const char * type,
965  const char * pattern = 0) = 0;
966 
967  /// Fill 'devlist' with devices of all 'types' with device names
968  /// specified by some optional 'pattern'.
969  /// Use platform specific default if 'types' is empty.
970  /// Return false on error.
971  /// Default implementation calls above function for all types
972  /// and concatenates the results.
973  virtual bool scan_smart_devices(smart_device_list & devlist,
974  const smart_devtype_list & types, const char * pattern = 0);
975 
976 protected:
977  /// Return standard ATA device.
978  virtual ata_device * get_ata_device(const char * name, const char * type) = 0;
979 
980  /// Return standard SCSI device.
981  virtual scsi_device * get_scsi_device(const char * name, const char * type) = 0;
982 
983  /// Return standard NVMe device.
984  /// Default implementation returns 0.
985  virtual nvme_device * get_nvme_device(const char * name, const char * type,
986  unsigned nsid);
987 
988  /// Autodetect device if no device type specified.
989  virtual smart_device * autodetect_smart_device(const char * name) = 0;
990 
991  /// Return device for platform specific 'type'.
992  /// Default implementation returns 0.
993  virtual smart_device * get_custom_smart_device(const char * name, const char * type);
994 
995  /// Return valid 'type' args accepted by above.
996  /// This is called in get_valid_dev_types_str().
997  /// Default implementation returns empty string.
998  virtual std::string get_valid_custom_dev_types_str();
999 
1000  /// Return ATA->SCSI filter for a SAT or USB 'type'.
1001  /// Device 'scsidev' is used for SCSI access.
1002  /// Return 0 and delete 'scsidev' on error.
1003  /// Override only if platform needs special handling.
1004  virtual ata_device * get_sat_device(const char * type, scsi_device * scsidev);
1005  //{ implemented in scsiata.cpp }
1006 
1007 public:
1008  /// Try to detect a SAT device behind a SCSI interface.
1009  /// Inquiry data can be passed if available.
1010  /// Return appropriate device if yes, otherwise 0.
1011  /// Override only if platform needs special handling.
1012  virtual ata_device * autodetect_sat_device(scsi_device * scsidev,
1013  const unsigned char * inqdata, unsigned inqsize);
1014  //{ implemented in scsiata.cpp }
1015 
1016  /// Get type name for USB device with known VENDOR:PRODUCT ID.
1017  /// Return name if device known and supported, otherwise 0.
1018  virtual const char * get_usb_dev_type_by_id(int vendor_id, int product_id,
1019  int version = -1);
1020  //{ implemented in scsiata.cpp }
1021 
1022 protected:
1023  /// Set interface to use, must be called from init().
1024  static void set(smart_interface * intf)
1025  { s_instance = intf; }
1026 
1027 // Implementation
1028 private:
1030 
1031  friend smart_interface * smi(); // below
1032  static smart_interface * s_instance; ///< Pointer to the interface object.
1033 
1034  // Prevent copy/assigment
1036  void operator=(const smart_interface &);
1037 };
1038 
1039 
1040 /////////////////////////////////////////////////////////////////////////////
1041 // smi()
1042 
1043 /// Global access to the (usually singleton) smart_interface
1045  { return smart_interface::s_instance; }
1046 
1047 /////////////////////////////////////////////////////////////////////////////
1048 
1049 #endif // DEV_INTERFACE_H
ata_reg_alias_48(ata_register &ll, ata_register &lm, ata_register &lh, ata_register &hl, ata_register &hm, ata_register &hh)
virtual int64_t get_timer_usec()
Get microseconds since some unspecified starting point.
Error (number,message) pair.
Definition: dev_interface.h:52
ata_reg_alias_16 & operator=(unsigned short x)
ata_reg_alias_16 sector_count_16
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.
Definition: scsiata.cpp:1561
int get_errno() const
Get last error number.
unsigned char direction() const
Get I/O direction from opcode.
u16 flags
Definition: megaraid.h:103
unsigned char m_val
Register value.
ATA Input registers for 48-bit commands.
ata_reg_alias_48 & operator=(uint64_t x)
ata_device * to_ata()
Downcast to ATA device.
Definition: dev_interface.h:96
ata_out_regs_flags out_needed
True if output register value needed.
const char * get_errmsg() const
Get last error message.
ata_reg_alias_16 sector_count_16
virtual std::string get_valid_dev_types_str()
Return valid args for device type option/directive.
std::string msg
Error message.
Definition: dev_interface.h:61
const char * get_dev_type() const
Get device type.
virtual ata_device * get_sat_device(const char *type, scsi_device *scsidev)
Return ATA->SCSI filter for a SAT or USB 'type'.
Definition: scsiata.cpp:1480
do_not_use_in_implementation_classes
Dummy enum for dummy constructor.
Definition: dev_interface.h:72
void set_rcap16_first()
Always try READ CAPACITY(10) (rcap10) first but once we know rcap16 is needed, use it instead...
ata_in_regs prev
"previous content"
ata_register error
any_device_auto_ptr< ata_device > ata_device_auto_ptr
smart_device::error_info m_err
ata_register lba_mid
uint64_t val() const
void set_data_out(const void *buf, unsigned nsectors)
Prepare for 28-bit DATA OUT command.
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.
any_device_auto_ptr< nvme_device > nvme_device_auto_ptr
ata_reg_alias_48 lba_48
void clear_err()
Clear last error info.
virtual bool scsi_pass_through(scsi_cmnd_io *iop)=0
SCSI pass through.
ata_reg_alias_16 lba_high_16
smart_device * at(unsigned i)
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.
ata_register & m_hh
virtual bool is_powered_down()
Early test if device is powered up or down.
void hide_scsi(bool hide=true)
Hide/unhide SCSI interface.
ata_register device
smart_interface * smi()
Global access to the (usually singleton) smart_interface.
virtual const char * get_msg_for_errno(int no)
Convert error number into message, used by set_err(no).
unsigned char val() const
smart_interface * m_intf
const smart_device::error_info & get_err() const
Get last error info struct.
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.
ata_register sector_count
unsigned cdw11
ata_register & m_lm
ATA Input registers (for 28-bit commands)
NVMe pass through input parameters.
friend smart_interface * smi()
Global access to the (usually singleton) smart_interface.
nvme_device(unsigned nsid)
Constructor requires namespace ID, registers device as NVMe.
device_info & set_info()
R/W access to device info struct.
#define __attribute_format_printf(x, y)
Definition: utility.h:34
16-bit alias to a 8-bit ATA register pair.
bool is_nvme() const
Return true if NVMe device.
Definition: dev_interface.h:92
ata_reg_alias_16 lba_high_16
void * buffer
Pointer to data buffer.
ata_device()
Default constructor, registers device as ATA.
NVMe pass through output parameters.
nvme_device * m_nvme_ptr
std::vector< smart_device * > m_list
void operator=(const smart_device &)
device_type * m_dev
void push_back(smart_device *dev)
bool operator!() const
For (ptr == 0) check.
ata_register lba_mid
scsi_device * to_scsi()
Downcast to SCSI device.
bool is_real_48bit_cmd() const
Return true if 48-bit command with any nonzero high byte.
device_info m_info
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.
virtual ~smart_interface()
48-bit alias to six 8-bit ATA registers (for LBA).
uint32_t nsid
void operator=(const smart_interface &)
ata_in_regs_48bit in_regs
Input registers.
ata_out_regs_48bit out_regs
Output registers.
std::string dev_type
Actual device type.
Definition: dev_interface.h:47
virtual ata_device * get_ata_device(const char *name, const char *type)=0
Return standard ATA device.
unsigned result
Command specific result (DW0)
List of devices for DEVICESCAN.
void set_data_in(void *buf, unsigned nsectors)
Prepare for 28-bit DATA IN command.
device_type * release()
Return the pointer and release ownership.
const ata_device * to_ata() const
Downcast to ATA device (const).
Definition: dev_interface.h:99
bool set_err_var(smart_device::error_info *err, int no)
Set last error number and default message to any error_info.
static int get_num_objects()
Get current number of allocated 'smart_device' objects.
device_type * get() const
Return the pointer.
virtual bool is_open() const =0
Return true if device is open.
ata_out_regs prev
read with HOB=1
bool m_is_set
true if set
static void init()
Initialize platform interface and register with smi().
Definition: dev_legacy.cpp:334
nvme_device * to_nvme()
Downcast to NVMe device.
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.
void operator=(const smart_device_list &)
device_info(const char *d_name, const char *d_type, const char *r_type)
Definition: dev_interface.h:40
void replace(device_type *dev)
Replace the pointer.
NVMe device access.
bool status_valid
true if status is valid
static void set(smart_interface *intf)
Set interface to use, must be called from init().
void * buffer
Pointer to data buffer.
error_info m_err
unsigned get_nsid() const
Get namespace id.
ata_register & m_hm
scsi_device * m_scsi_ptr
const char * get_errmsg() const
Get last error message.
static smart_interface * s_instance
Pointer to the interface object.
const scsi_device * to_scsi() const
Downcast to SCSI device (const).
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.
unsigned char opcode
Opcode (CDW0 07:00)
smart_device * release(unsigned i)
ATA Output registers for 48-bit commands.
const smart_device * at(unsigned i) const
ata_register & m_lo
bool is_ata() const
Return true if ATA device.
Definition: dev_interface.h:86
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'.
unsigned cdw12
ata_register status
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.
device_type & operator*() const
Pointer dereferencing.
unsigned size
Size of buffer.
ata_register lba_low
Device info strings.
Definition: dev_interface.h:37
unsigned cdw15
Cmd specific.
SCSI device access.
ata_reg_alias_16 lba_mid_16
unsigned nsid
Namespace ID.
ata_register features
void hide_ata(bool hide=true)
Hide/unhide ATA interface.
Flags for each ATA output register.
ata_register & operator=(unsigned char x)
unsigned size() const
ata_register & m_hl
void hide_nvme(bool hide=true)
Hide/unhide NVMe interface.
ata_register & m_lh
void set_data_in(unsigned char op, void *buf, unsigned sz)
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).
unsigned short val() const
bool is_scsi() const
Return true if SCSI device.
Definition: dev_interface.h:89
bool is_48bit_cmd() const
Return true if 48-bit command.
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.
Definition: scsiata.cpp:1593
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'...
~any_device_auto_ptr()
Destructor deletes device object.
ata_reg_alias_16 lba_low_16
ata_register device
Base class for all devices.
Definition: dev_interface.h:32
ata_device * m_ata_ptr
ata_register lba_high
int no
Error number.
Definition: dev_interface.h:60
ata_reg_alias_16 lba_low_16
ATA device access.
ata_register sector_count
device_type * operator->() const
Pointer dereferencing.
virtual bool disable_system_auto_standby(bool disable)
Disable/Enable system auto standby/sleep mode.
bool use_rcap16() const
virtual bool nvme_pass_through(const nvme_cmd_in &in, nvme_cmd_out &out)=0
NVMe pass through.
std::string dev_name
Device (path)name.
Definition: dev_interface.h:45
smart_device * m_base_dev
ata_register & m_hi
error_info(int n, const char *m)
Definition: dev_interface.h:55
bool is_set() const
Return true if any register is set.
unsigned size
Size of buffer.
void set_data_in_48bit(void *buf, unsigned nsectors)
Prepare for 48-bit DATA IN command.
virtual scsi_device * get_scsi_device(const char *name, const char *type)=0
Return standard SCSI device.
unsigned cdw13
ata_register command
const device_info & get_info() const
Get device info struct.
scsi_device()
Default constructor, registers device as SCSI.
void fail() const
any_device_auto_ptr< smart_device > smart_device_auto_ptr
any_device_auto_ptr< scsi_device > scsi_device_auto_ptr
virtual smart_device * autodetect_open()
Open device with autodetection support.
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.
void reset()
Delete device object and clear the pointer.
ATA pass through input parameters.
unsigned cdw10
const char va_list ap char buf[512+EBUFLEN]
Definition: smartd.cpp:1328
ata_register & m_ll
ata_reg_alias_16 lba_mid_16
const smart_interface * smi() const
Get interface which produced this object (const).
std::string req_type
Device type requested by user, empty if none.
Definition: dev_interface.h:48
virtual ~smart_device()
ata_register lba_low
void set_nsid(unsigned nsid)
Set namespace id.
void append(smart_device_list &devlist)
void push_back(smart_device_auto_ptr &dev)
ata_register lba_high
ata_reg_alias_16(ata_register &lo, ata_register &hi)
smart_interface * smi()
Get interface which produced this object.
const error_info & get_err() const
Get last error info struct.
ata_out_regs_flags()
Default constructor clears all flags.
void clear_err()
Clear last error info.
const char * get_dev_name() const
Get device (path)name.
unsigned short status
Status Field (DW3 31:17)
std::string info_name
Informal name.
Definition: dev_interface.h:46
bool is_set() const
void operator=(device_type *dev)
Assign a new pointer.
bool set_err(int no, const char *msg,...) __attribute_format_printf(3
Set last error number and message.
ATA Output registers (for 28-bit commands)
const char * get_req_type() const
Get type requested by user, empty if none.
unsigned m_nsid
virtual bool ata_identify_is_cached() const
Return true if OS caches ATA identify sector.
ata_reg_alias_16 features_16
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.
static int s_num_objects
ATA register value and info whether it has ever been set.
bool is_set() const
Return true if any register is set.
virtual std::string get_os_version_str()
Return info string about build host and/or OS version.
unsigned cdw14
const char * get_info_name() const
Get informal name.
const nvme_device * to_nvme() const
Downcast to NVMe device (const).
ata_reg_alias_48 lba_48