smartmontools  SVN Rev 4123
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-12 Christian Franke <smartmontools-support@lists.sourceforge.net>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2, or (at your option)
11  * any later version.
12  *
13  * You should have received a copy of the GNU General Public License
14  * (for example COPYING); If not, see <http://www.gnu.org/licenses/>.
15  *
16  */
17 
18 #ifndef DEV_INTERFACE_H
19 #define DEV_INTERFACE_H
20 
21 #define DEV_INTERFACE_H_CVSID "$Id: dev_interface.h 4120 2015-08-27 16:12:21Z samm2 $\n"
22 
23 #include "utility.h"
24 
25 #include <stdexcept>
26 #include <string>
27 #include <vector>
28 
29 /////////////////////////////////////////////////////////////////////////////
30 // Common functionality for all device types
31 
32 // Forward declarations
33 class smart_interface;
34 class ata_device;
35 class scsi_device;
36 
37 /// Base class for all devices
39 {
40 // Types
41 public:
42  /// Device info strings
43  struct device_info {
45  { }
46  device_info(const char * d_name, const char * d_type, const char * r_type)
47  : dev_name(d_name), info_name(d_name),
48  dev_type(d_type), req_type(r_type)
49  { }
50 
51  std::string dev_name; ///< Device (path)name
52  std::string info_name; ///< Informal name
53  std::string dev_type; ///< Actual device type
54  std::string req_type; ///< Device type requested by user, empty if none
55  };
56 
57  /// Error (number,message) pair
58  struct error_info {
59  explicit error_info(int n = 0)
60  : no(n) { }
61  error_info(int n, const char * m)
62  : no(n), msg(m) { }
63  void clear()
64  { no = 0; msg.erase(); }
65 
66  int no; ///< Error number
67  std::string msg; ///< Error message
68  };
69 
70 // Construction
71 protected:
72  /// Constructor to init interface and device info.
73  /// Must be called in implementation classes.
74  smart_device(smart_interface * intf, const char * dev_name,
75  const char * dev_type, const char * req_type);
76 
77  /// Dummy enum for dummy constructor.
79  /// Dummy constructor for abstract classes.
80  /// Must never be called in implementation classes.
82 
83 public:
84  virtual ~smart_device() throw();
85 
86 // Attributes
87 public:
88  ///////////////////////////////////////////////
89  // Dynamic downcasts to actual device flavor
90 
91  /// Return true if ATA device
92  bool is_ata() const
93  { return !!m_ata_ptr; }
94  /// Return true if SCSI device
95  bool is_scsi() const
96  { return !!m_scsi_ptr; }
97 
98  /// Downcast to ATA device.
100  { return m_ata_ptr; }
101  /// Downcast to ATA device (const).
102  const ata_device * to_ata() const
103  { return m_ata_ptr; }
104  /// Downcast to SCSI device.
106  { return m_scsi_ptr; }
107  /// Downcast to SCSI device (const).
108  const scsi_device * to_scsi() const
109  { return m_scsi_ptr; }
110 
111  ///////////////////////////////////////////////
112  // Device information
113 
114  /// Get device info struct.
115  const device_info & get_info() const
116  { return m_info; }
117 
118  /// Get device (path)name.
119  const char * get_dev_name() const
120  { return m_info.dev_name.c_str(); }
121  /// Get informal name.
122  const char * get_info_name() const
123  { return m_info.info_name.c_str(); }
124  /// Get device type.
125  const char * get_dev_type() const
126  { return m_info.dev_type.c_str(); }
127  /// Get type requested by user, empty if none.
128  const char * get_req_type() const
129  { return m_info.req_type.c_str(); }
130 
131 protected:
132  /// R/W access to device info struct.
134  { return m_info; }
135 
136 public:
137  ///////////////////////////////////////////////
138  // Last error information
139 
140  /// Get last error info struct.
141  const error_info & get_err() const
142  { return m_err; }
143  /// Get last error number.
144  int get_errno() const
145  { return m_err.no; }
146  /// Get last error message.
147  const char * get_errmsg() const
148  { return m_err.msg.c_str(); }
149 
150  /// Return true if last error indicates an unsupported system call.
151  /// Default implementation returns true on ENOSYS and ENOTSUP.
152  virtual bool is_syscall_unsup() const;
153 
154  /// Set last error number and message.
155  /// Printf()-like formatting is supported.
156  /// Returns false always to allow use as a return expression.
157  bool set_err(int no, const char * msg, ...)
159 
160  /// Set last error info struct.
161  bool set_err(const error_info & err)
162  { m_err = err; return false; }
163 
164  /// Clear last error info.
165  void clear_err()
166  { m_err.clear(); }
167 
168  /// Set last error number and default message.
169  /// Message is retrieved from interface's get_msg_for_errno(no).
170  bool set_err(int no);
171 
172 // Operations
173 public:
174  ///////////////////////////////////////////////
175  // Device open/close
176  // Must be implemented in derived class
177 
178  /// Return true if device is open.
179  virtual bool is_open() const = 0;
180 
181  /// Open device, return false on error.
182  virtual bool open() = 0;
183 
184  /// Close device, return false on error.
185  virtual bool close() = 0;
186 
187  /// Open device with autodetection support.
188  /// May return another device for further access.
189  /// In this case, the original pointer is no longer valid.
190  /// Default implementation calls 'open()' and returns 'this'.
191  virtual smart_device * autodetect_open();
192 
193  ///////////////////////////////////////////////
194  // Support for tunnelled devices
195 
196  /// Return true if other device is owned by this device.
197  /// Default implementation returns false.
198  virtual bool owns(const smart_device * dev) const;
199 
200  /// Release ownership of other device.
201  /// Default implementation does nothing.
202  virtual void release(const smart_device * dev);
203 
204 protected:
205  /// Get interface which produced this object.
207  { return m_intf; }
208  /// Get interface which produced this object (const).
209  const smart_interface * smi() const
210  { return m_intf; }
211 
212 // Implementation
213 private:
217 
218  // Pointers for to_ata(), to_scsi(),
219  // set by ATA/SCSI interface classes.
220  friend class ata_device;
222  friend class scsi_device;
224 
225  // Prevent copy/assigment
226  smart_device(const smart_device &);
227  void operator=(const smart_device &);
228 };
229 
230 
231 /////////////////////////////////////////////////////////////////////////////
232 // ATA specific interface
233 
234 /// ATA register value and info whether it has ever been set
235 // (Automatically set by first assignment)
237 {
238 public:
240  : m_val(0x00), m_is_set(false) { }
241 
242  ata_register & operator=(unsigned char x)
243  { m_val = x; m_is_set = true; return * this; }
244 
245  unsigned char val() const
246  { return m_val; }
247  operator unsigned char() const
248  { return m_val; }
249 
250  bool is_set() const
251  { return m_is_set; }
252 
253 private:
254  unsigned char m_val; ///< Register value
255  bool m_is_set; ///< true if set
256 };
257 
258 /// ATA Input registers (for 28-bit commands)
260 {
261  // ATA-6/7 register names // ATA-3/4/5 // ATA-8
262  ata_register features; // features // features
263  ata_register sector_count; // sector count // count
264  ata_register lba_low; // sector number // ]
265  ata_register lba_mid; // cylinder low // ] lba
266  ata_register lba_high; // cylinder high // ]
267  ata_register device; // device/head // device
268  ata_register command; // command // command
269 
270  /// Return true if any register is set
271  bool is_set() const
272  { return (features.is_set() || sector_count.is_set()
273  || lba_low.is_set() || lba_mid.is_set() || lba_high.is_set()
274  || device.is_set() || command.is_set()); }
275 };
276 
277 /// ATA Output registers (for 28-bit commands)
279 {
287 
288  /// Return true if any register is set
289  bool is_set() const
290  { return (error.is_set() || sector_count.is_set()
291  || lba_low.is_set() || lba_mid.is_set() || lba_high.is_set()
292  || device.is_set() || status.is_set()); }
293 };
294 
295 
296 /// 16-bit alias to a 8-bit ATA register pair.
298 {
299 public:
301  : m_lo(lo), m_hi(hi) { }
302 
303  ata_reg_alias_16 & operator=(unsigned short x)
304  { m_lo = (unsigned char) x;
305  m_hi = (unsigned char)(x >> 8);
306  return * this; }
307 
308  unsigned short val() const
309  { return m_lo | (m_hi << 8); }
310  operator unsigned short() const
311  { return m_lo | (m_hi << 8); }
312 
313 private:
315 
316  // References must not be copied.
318  void operator=(const ata_reg_alias_16 &);
319 };
320 
321 
322 /// 48-bit alias to six 8-bit ATA registers (for LBA).
324 {
325 public:
327  ata_register & hl, ata_register & hm, ata_register & hh)
328  : m_ll(ll), m_lm(lm), m_lh(lh),
329  m_hl(hl), m_hm(hm), m_hh(hh)
330  { }
331 
333  {
334  m_ll = (unsigned char) x;
335  m_lm = (unsigned char)(x >> 8);
336  m_lh = (unsigned char)(x >> 16);
337  m_hl = (unsigned char)(x >> 24);
338  m_hm = (unsigned char)(x >> 32);
339  m_hh = (unsigned char)(x >> 40);
340  return * this;
341  }
342 
343  uint64_t val() const
344  {
345  return ( (unsigned)m_ll
346  | ((unsigned)m_lm << 8)
347  | ((unsigned)m_lh << 16)
348  | ((unsigned)m_hl << 24)
349  | ((uint64_t)m_hm << 32)
350  | ((uint64_t)m_hh << 40));
351  }
352 
353  operator uint64_t() const
354  { return val(); }
355 
356 private:
358  & m_hl, & m_hm, & m_hh;
359 
360  // References must not be copied.
362  void operator=(const ata_reg_alias_48 &);
363 };
364 
365 
366 /// ATA Input registers for 48-bit commands
367 // See section 4.14 of T13/1532D Volume 1 Revision 4b
368 //
369 // Uses ATA-6/7 method to specify 16-bit registers as
370 // recent (low byte) and previous (high byte) content of
371 // 8-bit registers.
372 //
373 // (ATA-8 ACS does not longer follow this scheme, it uses
374 // abstract registers with sufficient size and leaves the
375 // actual mapping to the transport layer.)
376 //
378 : public ata_in_regs // "most recently written" registers
379 {
380  ata_in_regs prev; ///< "previous content"
381 
382  // 16-bit aliases for above pair.
388 
389  // 48-bit alias to all 8-bit LBA registers.
391 
392  /// Return true if 48-bit command
393  bool is_48bit_cmd() const
394  { return prev.is_set(); }
395 
396  /// Return true if 48-bit command with any nonzero high byte
397  bool is_real_48bit_cmd() const
398  { return ( prev.features || prev.sector_count
399  || prev.lba_low || prev.lba_mid || prev.lba_high); }
400 
402 };
403 
404 
405 /// ATA Output registers for 48-bit commands
407 : public ata_out_regs // read with HOB=0
408 {
409  ata_out_regs prev; ///< read with HOB=1
410 
411  // 16-bit aliases for above pair.
416 
417  // 48-bit alias to all 8-bit LBA registers.
419 
421 };
422 
423 
424 /// Flags for each ATA output register
426 {
428 
429  /// Return true if any flag is set.
430  bool is_set() const
431  { return ( error || sector_count || lba_low
432  || lba_mid || lba_high || device || status); }
433 
434  /// Default constructor clears all flags.
436  : error(false), sector_count(false), lba_low(false), lba_mid(false),
437  lba_high(false), device(false), status(false) { }
438 };
439 
440 
441 /// ATA pass through input parameters
443 {
444  ata_in_regs_48bit in_regs; ///< Input registers
445  ata_out_regs_flags out_needed; ///< True if output register value needed
446  enum { no_data = 0, data_in, data_out } direction; ///< I/O direction
447  void * buffer; ///< Pointer to data buffer
448  unsigned size; ///< Size of buffer
449 
450  /// Prepare for 28-bit DATA IN command
451  void set_data_in(void * buf, unsigned nsectors)
452  {
453  buffer = buf;
454  in_regs.sector_count = nsectors;
455  direction = data_in;
456  size = nsectors * 512;
457  }
458 
459  /// Prepare for 28-bit DATA OUT command
460  void set_data_out(const void * buf, unsigned nsectors)
461  {
462  buffer = const_cast<void *>(buf);
463  in_regs.sector_count = nsectors;
465  size = nsectors * 512;
466  }
467 
468  /// Prepare for 48-bit DATA IN command
469  void set_data_in_48bit(void * buf, unsigned nsectors)
470  {
471  buffer = buf;
472  // Note: This also sets 'in_regs.is_48bit_cmd()'
473  in_regs.sector_count_16 = nsectors;
474  direction = data_in;
475  size = nsectors * 512;
476  }
477 
478  ata_cmd_in();
479 };
480 
481 /// ATA pass through output parameters
483 {
484  ata_out_regs_48bit out_regs; ///< Output registers
485 
486  ata_cmd_out();
487 };
488 
489 /// ATA device access
491 : virtual public /*extends*/ smart_device
492 {
493 public:
494  /// ATA pass through.
495  /// Return false on error.
496  /// Must be implemented in derived class.
497  virtual bool ata_pass_through(const ata_cmd_in & in, ata_cmd_out & out) = 0;
498 
499  /// ATA pass through without output registers.
500  /// Return false on error.
501  /// Calls ata_pass_through(in, dummy), cannot be reimplemented.
502  bool ata_pass_through(const ata_cmd_in & in);
503 
504  /// Return true if OS caches ATA identify sector.
505  /// Default implementation returns false.
506  virtual bool ata_identify_is_cached() const;
507 
508 protected:
509  /// Flags for ata_cmd_is_supported().
510  enum {
511  supports_data_out = 0x01, // PIO DATA OUT
512  supports_smart_status = 0x02, // read output registers for SMART STATUS only
513  supports_output_regs = 0x04, // read output registers for all commands
514  supports_multi_sector = 0x08, // more than one sector (1 DRQ/sector variant)
515  supports_48bit_hi_null = 0x10, // 48-bit commands with null high bytes only
516  supports_48bit = 0x20, // all 48-bit commands
517  };
518 
519  /// Check command input parameters.
520  /// Return false if required features are not implemented.
521  /// Calls set_err(...) accordingly.
522  bool ata_cmd_is_supported(const ata_cmd_in & in, unsigned flags,
523  const char * type = 0);
524 
525  /// Check command input parameters (old version).
526  // TODO: Remove if no longer used.
527  bool ata_cmd_is_ok(const ata_cmd_in & in,
528  bool data_out_support = false,
529  bool multi_sector_support = false,
530  bool ata_48bit_support = false)
531  {
532  return ata_cmd_is_supported(in,
533  (data_out_support ? supports_data_out : 0) |
535  (multi_sector_support ? supports_multi_sector : 0) |
536  (ata_48bit_support ? supports_48bit : 0));
537  }
538 
539  /// Hide/unhide ATA interface.
540  void hide_ata(bool hide = true)
541  { m_ata_ptr = (!hide ? this : 0); }
542 
543  /// Default constructor, registers device as ATA.
546  { hide_ata(false); }
547 };
548 
549 
550 /////////////////////////////////////////////////////////////////////////////
551 // SCSI specific interface
552 
553 struct scsi_cmnd_io;
554 
555 /// SCSI device access
557 : virtual public /*extends*/ smart_device
558 {
559 public:
560  /// SCSI pass through.
561  /// Returns false on error.
562  virtual bool scsi_pass_through(scsi_cmnd_io * iop) = 0;
563 
564 protected:
565  /// Hide/unhide SCSI interface.
566  void hide_scsi(bool hide = true)
567  { m_scsi_ptr = (!hide ? this : 0); }
568 
569  /// Default constructor, registers device as SCSI.
572  { hide_scsi(false); }
573 };
574 
575 
576 /////////////////////////////////////////////////////////////////////////////
577 /// Smart pointer class for device pointers
578 
579 template <class Dev>
581 {
582 public:
583  typedef Dev device_type;
584 
585  /// Construct from optional pointer to device
586  /// and optional pointer to base device.
587  explicit any_device_auto_ptr(device_type * dev = 0,
588  smart_device * base_dev = 0)
589  : m_dev(dev), m_base_dev(base_dev) { }
590 
591  /// Destructor deletes device object.
593  { reset(); }
594 
595  /// Assign a new pointer.
596  /// Throws if a pointer is already assigned.
597  void operator=(device_type * dev)
598  {
599  if (m_dev)
600  fail();
601  m_dev = dev;
602  }
603 
604  /// Delete device object and clear the pointer.
605  void reset()
606  {
607  if (m_dev) {
608  if (m_base_dev && m_dev->owns(m_base_dev))
609  m_dev->release(m_base_dev);
610  delete m_dev;
611  m_dev = 0;
612  }
613  }
614 
615  /// Return the pointer and release ownership.
616  device_type * release()
617  {
618  device_type * dev = m_dev;
619  m_dev = 0;
620  return dev;
621  }
622 
623  /// Replace the pointer.
624  /// Used to call dev->autodetect_open().
625  void replace(device_type * dev)
626  { m_dev = dev; }
627 
628  /// Return the pointer.
629  device_type * get() const
630  { return m_dev; }
631 
632  /// Pointer dereferencing.
633  device_type & operator*() const
634  { return *m_dev; }
635 
636  /// Pointer dereferencing.
637  device_type * operator->() const
638  { return m_dev; }
639 
640  /// For (ptr != 0) check.
641  operator bool() const
642  { return !!m_dev; }
643 
644  /// For (ptr == 0) check.
645  bool operator !() const
646  { return !m_dev; }
647 
648 private:
649  device_type * m_dev;
651 
652  void fail() const
653  { throw std::logic_error("any_device_auto_ptr: wrong usage"); }
654 
655  // Prevent copy/assignment
657  void operator=(const any_device_auto_ptr<Dev> &);
658 };
659 
663 
664 
665 /////////////////////////////////////////////////////////////////////////////
666 // smart_device_list
667 
668 /// List of devices for DEVICESCAN
670 {
671 // Construction
672 public:
674  { }
675 
677  {
678  for (unsigned i = 0; i < m_list.size(); i++)
679  delete m_list[i];
680  }
681 
682 // Attributes
683  unsigned size() const
684  { return m_list.size(); }
685 
686 // Operations
687  void clear()
688  {
689  for (unsigned i = 0; i < m_list.size(); i++)
690  delete m_list[i];
691  m_list.clear();
692  }
693 
694 
696  { m_list.push_back(dev); }
697 
699  {
700  m_list.push_back(dev.get());
701  dev.release();
702  }
703 
704  smart_device * at(unsigned i)
705  { return m_list.at(i); }
706 
707  const smart_device * at(unsigned i) const
708  { return m_list.at(i); }
709 
710  smart_device * release(unsigned i)
711  {
712  smart_device * dev = m_list.at(i);
713  m_list[i] = 0;
714  return dev;
715  }
716 
717 // Implementation
718 private:
719  std::vector<smart_device *> m_list;
720 
721  // Prevent copy/assigment
723  void operator=(const smart_device_list &);
724 };
725 
726 
727 /////////////////////////////////////////////////////////////////////////////
728 // smart_interface
729 
730 /// The platform interface abstraction
732 {
733 public:
734  /// Initialize platform interface and register with smi().
735  /// Must be implemented by platform module and register interface with set()
736  static void init();
737 
739  { }
740 
741  virtual ~smart_interface() throw()
742  { }
743 
744  /// Return info string about build host and/or OS version.
745  /// Default implementation returns SMARTMONTOOLS_BUILD_HOST.
746  virtual std::string get_os_version_str();
747 
748  /// Return valid args for device type option/directive.
749  /// Default implementation returns "ata, scsi, sat, usb*..."
750  /// concatenated with result from get_valid_custom_dev_types_str().
751  virtual std::string get_valid_dev_types_str();
752 
753  /// Return example string for program 'appname'.
754  /// Default implementation returns empty string.
755  /// For the migration of print_smartctl_examples(),
756  /// function is allowed to print examples to stdout.
757  /// TODO: Remove this hack.
758  virtual std::string get_app_examples(const char * appname);
759 
760  /// Get microseconds since some unspecified starting point.
761  /// Used only for command duration measurements in debug outputs.
762  /// Returns -1 if unsupported.
763  /// Default implementation uses clock_gettime(), gettimeofday() or ftime().
764  virtual int64_t get_timer_usec();
765 
766  /// Disable/Enable system auto standby/sleep mode.
767  /// Return false if unsupported or if system is running
768  /// on battery.
769  /// Default implementation returns false.
770  virtual bool disable_system_auto_standby(bool disable);
771 
772 
773  ///////////////////////////////////////////////
774  // Last error information
775 
776  /// Get last error info struct.
778  { return m_err; }
779  /// Get last error number.
780  int get_errno() const
781  { return m_err.no; }
782  /// Get last error message.
783  const char * get_errmsg() const
784  { return m_err.msg.c_str(); }
785 
786  /// Set last error number and message.
787  /// Printf()-like formatting is supported.
788  /// Returns false always to allow use as a return expression.
789  bool set_err(int no, const char * msg, ...)
791 
792  /// Set last error info struct.
793  bool set_err(const smart_device::error_info & err)
794  { m_err = err; return false; }
795 
796  /// Clear last error info.
797  void clear_err()
798  { m_err.clear(); }
799 
800  /// Set last error number and default message.
801  /// Message is retrieved from get_msg_for_errno(no).
802  bool set_err(int no);
803 
804  /// Set last error number and default message to any error_info.
805  /// Used by set_err(no).
806  bool set_err_var(smart_device::error_info * err, int no);
807 
808  /// Convert error number into message, used by set_err(no).
809  /// Default implementation returns strerror(no).
810  virtual const char * get_msg_for_errno(int no);
811 
812  ///////////////////////////////////////////////////////////////////////////
813  // Device factory:
814 
815  /// Return device object for device 'name' with some 'type'.
816  /// 'type' is 0 if not specified by user.
817  /// Return 0 on error.
818  /// Default implementation selects between ata, scsi and custom device.
819  virtual smart_device * get_smart_device(const char * name, const char * type);
820 
821  /// Fill 'devlist' with devices of some 'type' with device names
822  /// specified by some optional 'pattern'.
823  /// Return false on error.
824  virtual bool scan_smart_devices(smart_device_list & devlist, const char * type,
825  const char * pattern = 0) = 0;
826 
827 protected:
828  /// Return standard ATA device.
829  virtual ata_device * get_ata_device(const char * name, const char * type) = 0;
830 
831  /// Return standard SCSI device.
832  virtual scsi_device * get_scsi_device(const char * name, const char * type) = 0;
833 
834  /// Autodetect device if no device type specified.
835  virtual smart_device * autodetect_smart_device(const char * name) = 0;
836 
837  /// Return device for platform specific 'type'.
838  /// Default implementation returns 0.
839  virtual smart_device * get_custom_smart_device(const char * name, const char * type);
840 
841  /// Return valid 'type' args accepted by above.
842  /// This is called in get_valid_dev_types_str().
843  /// Default implementation returns empty string.
844  virtual std::string get_valid_custom_dev_types_str();
845 
846  /// Return ATA->SCSI filter for SAT or USB.
847  /// Override only if platform needs special handling.
848  virtual ata_device * get_sat_device(const char * type, scsi_device * scsidev);
849  //{ implemented in scsiata.cpp }
850 
851 public:
852  /// Try to detect a SAT device behind a SCSI interface.
853  /// Inquiry data can be passed if available.
854  /// Return appropriate device if yes, otherwise 0.
855  /// Override only if platform needs special handling.
856  virtual ata_device * autodetect_sat_device(scsi_device * scsidev,
857  const unsigned char * inqdata, unsigned inqsize);
858  //{ implemented in scsiata.cpp }
859 
860  /// Get type name for USB device with known VENDOR:PRODUCT ID.
861  /// Return name if device known and supported, otherwise 0.
862  virtual const char * get_usb_dev_type_by_id(int vendor_id, int product_id,
863  int version = -1);
864  //{ implemented in scsiata.cpp }
865 
866 protected:
867  /// Set interface to use, must be called from init().
868  static void set(smart_interface * intf)
869  { s_instance = intf; }
870 
871 // Implementation
872 private:
874 
875  friend smart_interface * smi(); // below
876  static smart_interface * s_instance; ///< Pointer to the interface object.
877 
878  // Prevent copy/assigment
880  void operator=(const smart_interface &);
881 };
882 
883 
884 /////////////////////////////////////////////////////////////////////////////
885 // smi()
886 
887 /// Global access to the (usually singleton) smart_interface
889  { return smart_interface::s_instance; }
890 
891 /////////////////////////////////////////////////////////////////////////////
892 
893 #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:58
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:1552
int get_errno() const
Get last error number.
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:99
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:67
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 SAT or USB.
Definition: scsiata.cpp:1486
do_not_use_in_implementation_classes
Dummy enum for dummy constructor.
Definition: dev_interface.h:78
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.
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)
Smart pointer class for device pointers.
ata_register & m_hh
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
ata_register & m_lm
ATA Input registers (for 28-bit commands)
friend smart_interface * smi()
Global access to the (usually singleton) smart_interface.
device_info & set_info()
R/W access to device info struct.
#define __attribute_format_printf(x, y)
Definition: utility.h:39
u16 flags
Definition: megaraid.h:93
16-bit alias to a 8-bit ATA register pair.
ata_reg_alias_16 lba_high_16
void * buffer
Pointer to data buffer.
ata_device()
Default constructor, registers device as ATA.
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).
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:53
virtual ata_device * get_ata_device(const char *name, const char *type)=0
Return standard ATA device.
List of devices for DEVICESCAN.
enum ata_cmd_in::@27 direction
I/O direction.
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).
bool set_err_var(smart_device::error_info *err, int no)
Set last error number and default message to any error_info.
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:338
The platform interface abstraction.
virtual bool ata_pass_through(const ata_cmd_in &in, ata_cmd_out &out)=0
ATA pass through.
void operator=(const smart_device_list &)
device_info(const char *d_name, const char *d_type, const char *r_type)
Definition: dev_interface.h:46
void replace(device_type *dev)
Replace the pointer.
static void set(smart_interface *intf)
Set interface to use, must be called from init().
error_info m_err
ata_register & m_hm
scsi_device * m_scsi_ptr
const char * get_errmsg() const
Get last error message.
long long int64_t
Definition: int64.h:51
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.
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:92
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'.
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:43
SCSI device access.
ata_reg_alias_16 lba_mid_16
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
ata_register & m_lh
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:95
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:1582
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:38
ata_device * m_ata_ptr
ata_register lba_high
int no
Error number.
Definition: dev_interface.h:66
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.
unsigned long long uint64_t
Definition: int64.h:54
std::string dev_name
Device (path)name.
Definition: dev_interface.h:51
smart_device * m_base_dev
ata_register & m_hi
error_info(int n, const char *m)
Definition: dev_interface.h:61
bool is_set() const
Return true if any register is set.
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.
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.
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:54
virtual ~smart_device()
ata_register lba_low
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.
std::string info_name
Informal name.
Definition: dev_interface.h:52
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.
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.
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.
const char * get_info_name() const
Get informal name.
ata_reg_alias_48 lba_48