4 * Home page of code is: http://www.smartmontools.org
6 * Copyright (C) 2008-18 Christian Franke
8 * SPDX-License-Identifier: GPL-2.0-or-later
11 #ifndef DEV_INTERFACE_H
12 #define DEV_INTERFACE_H
14 #define DEV_INTERFACE_H_CVSID "$Id: dev_interface.h 4848 2018-12-05 18:30:46Z chrfranke $\n"
22 /////////////////////////////////////////////////////////////////////////////
23 // Common functionality for all device types
25 // Forward declarations
26 class smart_interface
;
31 /// Base class for all devices
36 /// Device info strings
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
)
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
51 /// Error (number,message) pair
53 explicit error_info(int n
= 0)
55 error_info(int n
, const char * m
)
58 { no
= 0; msg
.erase(); }
60 int no
; ///< Error number
61 std::string msg
; ///< Error message
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
);
71 /// Dummy enum for dummy constructor.
72 enum do_not_use_in_implementation_classes
{ never_called
};
73 /// Dummy constructor for abstract classes.
74 /// Must never be called in implementation classes.
75 explicit smart_device(do_not_use_in_implementation_classes
);
78 virtual ~smart_device() throw();
82 ///////////////////////////////////////////////
83 // Dynamic downcasts to actual device flavor
85 /// Return true if ATA device
87 { return !!m_ata_ptr
; }
88 /// Return true if SCSI device
90 { return !!m_scsi_ptr
; }
91 /// Return true if NVMe device
93 { return !!m_nvme_ptr
; }
95 /// Downcast to ATA device.
98 /// Downcast to ATA device (const).
99 const ata_device
* to_ata() const
100 { return m_ata_ptr
; }
101 /// Downcast to SCSI device.
102 scsi_device
* to_scsi()
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.
108 nvme_device
* to_nvme()
109 { return m_nvme_ptr
; }
110 /// Downcast to NVMe device (const).
111 const nvme_device
* to_nvme() const
112 { return m_nvme_ptr
; }
114 ///////////////////////////////////////////////
115 // Device information
117 /// Get device info struct.
118 const device_info
& get_info() const
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(); }
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(); }
135 /// R/W access to device info struct.
136 device_info
& set_info()
140 ///////////////////////////////////////////////
141 // Last error information
143 /// Get last error info struct.
144 const error_info
& get_err() const
146 /// Get last error number.
147 int get_errno() const
149 /// Get last error message.
150 const char * get_errmsg() const
151 { return m_err
.msg
.c_str(); }
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;
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
, ...)
161 __attribute_format_printf(3, 4);
163 /// Set last error info struct.
164 bool set_err(const error_info
& err
)
165 { m_err
= err
; return false; }
167 /// Clear last error info.
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
);
175 /// Get current number of allocated 'smart_device' objects.
176 static int get_num_objects()
177 { return s_num_objects
; }
181 ///////////////////////////////////////////////
183 // Must be implemented in derived class
185 /// Return true if device is open.
186 virtual bool is_open() const = 0;
188 /// Open device, return false on error.
189 virtual bool open() = 0;
191 /// Close device, return false on error.
192 virtual bool close() = 0;
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();
200 ///////////////////////////////////////////////
201 // Support for checking power mode reported by operating system
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();
211 ///////////////////////////////////////////////
212 // Support for tunnelled devices
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;
218 /// Release ownership of other device.
219 /// Default implementation does nothing.
220 virtual void release(const smart_device
* dev
);
223 /// Get interface which produced this object.
224 smart_interface
* smi()
226 /// Get interface which produced this object (const).
227 const smart_interface
* smi() const
232 smart_interface
* m_intf
;
236 // Pointers for to_ata(), to_scsi(), to_nvme()
237 // set by ATA/SCSI/NVMe interface classes.
238 friend class ata_device
;
239 ata_device
* m_ata_ptr
;
240 friend class scsi_device
;
241 scsi_device
* m_scsi_ptr
;
242 friend class nvme_device
;
243 nvme_device
* m_nvme_ptr
;
245 // Number of objects.
246 static int s_num_objects
;
248 // Prevent copy/assignment
249 smart_device(const smart_device
&);
250 void operator=(const smart_device
&);
254 /////////////////////////////////////////////////////////////////////////////
255 // ATA specific interface
257 /// ATA register value and info whether it has ever been set
258 // (Automatically set by first assignment)
263 : m_val(0x00), m_is_set(false) { }
265 ata_register
& operator=(unsigned char x
)
266 { m_val
= x
; m_is_set
= true; return * this; }
268 unsigned char val() const
270 operator unsigned char() const
277 unsigned char m_val
; ///< Register value
278 bool m_is_set
; ///< true if set
281 /// ATA Input registers (for 28-bit commands)
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
293 /// Return true if any register is set
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()); }
300 /// ATA Output registers (for 28-bit commands)
304 ata_register sector_count
;
305 ata_register lba_low
;
306 ata_register lba_mid
;
307 ata_register lba_high
;
311 /// Return true if any register is set
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()); }
319 /// 16-bit alias to a 8-bit ATA register pair.
320 class ata_reg_alias_16
323 ata_reg_alias_16(ata_register
& lo
, ata_register
& hi
)
324 : m_lo(lo
), m_hi(hi
) { }
326 ata_reg_alias_16
& operator=(unsigned short x
)
327 { m_lo
= (unsigned char) x
;
328 m_hi
= (unsigned char)(x
>> 8);
331 unsigned short val() const
332 { return m_lo
| (m_hi
<< 8); }
333 operator unsigned short() const
334 { return m_lo
| (m_hi
<< 8); }
337 ata_register
& m_lo
, & m_hi
;
339 // References must not be copied.
340 ata_reg_alias_16(const ata_reg_alias_16
&);
341 void operator=(const ata_reg_alias_16
&);
345 /// 48-bit alias to six 8-bit ATA registers (for LBA).
346 class ata_reg_alias_48
349 ata_reg_alias_48(ata_register
& ll
, ata_register
& lm
, ata_register
& lh
,
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
)
355 ata_reg_alias_48
& operator=(uint64_t x
)
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);
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));
376 operator uint64_t() const
380 ata_register
& m_ll
, & m_lm
, & m_lh
,
381 & m_hl
, & m_hm
, & m_hh
;
383 // References must not be copied.
384 ata_reg_alias_48(const ata_reg_alias_48
&);
385 void operator=(const ata_reg_alias_48
&);
389 /// ATA Input registers for 48-bit commands
390 // See section 4.14 of T13/1532D Volume 1 Revision 4b
392 // Uses ATA-6/7 method to specify 16-bit registers as
393 // recent (low byte) and previous (high byte) content of
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.)
400 struct ata_in_regs_48bit
401 : public ata_in_regs
// "most recently written" registers
403 ata_in_regs prev
; ///< "previous content"
405 // 16-bit aliases for above pair.
406 ata_reg_alias_16 features_16
;
407 ata_reg_alias_16 sector_count_16
;
408 ata_reg_alias_16 lba_low_16
;
409 ata_reg_alias_16 lba_mid_16
;
410 ata_reg_alias_16 lba_high_16
;
412 // 48-bit alias to all 8-bit LBA registers.
413 ata_reg_alias_48 lba_48
;
415 /// Return true if 48-bit command
416 bool is_48bit_cmd() const
417 { return prev
.is_set(); }
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
); }
428 /// ATA Output registers for 48-bit commands
429 struct ata_out_regs_48bit
430 : public ata_out_regs
// read with HOB=0
432 ata_out_regs prev
; ///< read with HOB=1
434 // 16-bit aliases for above pair.
435 ata_reg_alias_16 sector_count_16
;
436 ata_reg_alias_16 lba_low_16
;
437 ata_reg_alias_16 lba_mid_16
;
438 ata_reg_alias_16 lba_high_16
;
440 // 48-bit alias to all 8-bit LBA registers.
441 ata_reg_alias_48 lba_48
;
443 ata_out_regs_48bit();
447 /// Flags for each ATA output register
448 struct ata_out_regs_flags
450 bool error
, sector_count
, lba_low
, lba_mid
, lba_high
, device
, status
;
452 /// Return true if any flag is set.
454 { return ( error
|| sector_count
|| lba_low
455 || lba_mid
|| lba_high
|| device
|| status
); }
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) { }
464 /// ATA pass through input parameters
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
473 /// Prepare for 28-bit DATA IN command
474 void set_data_in(void * buf
, unsigned nsectors
)
477 in_regs
.sector_count
= nsectors
;
479 size
= nsectors
* 512;
482 /// Prepare for 28-bit DATA OUT command
483 void set_data_out(const void * buf
, unsigned nsectors
)
485 buffer
= const_cast<void *>(buf
);
486 in_regs
.sector_count
= nsectors
;
487 direction
= data_out
;
488 size
= nsectors
* 512;
491 /// Prepare for 48-bit DATA IN command
492 void set_data_in_48bit(void * buf
, unsigned nsectors
)
495 // Note: This also sets 'in_regs.is_48bit_cmd()'
496 in_regs
.sector_count_16
= nsectors
;
498 size
= nsectors
* 512;
504 /// ATA pass through output parameters
507 ata_out_regs_48bit out_regs
; ///< Output registers
512 /// ATA device access
514 : virtual public /*extends*/ smart_device
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;
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
);
527 /// Return true if OS caches ATA identify sector.
528 /// Default implementation returns false.
529 virtual bool ata_identify_is_cached() const;
532 /// Flags for ata_cmd_is_supported().
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
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);
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)
555 return ata_cmd_is_supported(in
,
556 (data_out_support
? supports_data_out
: 0) |
557 supports_output_regs
|
558 (multi_sector_support
? supports_multi_sector
: 0) |
559 (ata_48bit_support
? supports_48bit
: 0));
562 /// Hide/unhide ATA interface.
563 void hide_ata(bool hide
= true)
564 { m_ata_ptr
= (!hide
? this : 0); }
566 /// Default constructor, registers device as ATA.
568 : smart_device(never_called
)
573 /////////////////////////////////////////////////////////////////////////////
574 // SCSI specific interface
578 /// SCSI device access
580 : virtual public /*extends*/ smart_device
583 /// SCSI pass through.
584 /// Returns false on error.
585 virtual bool scsi_pass_through(scsi_cmnd_io
* iop
) = 0;
587 // Call scsi_pass_through and check sense.
588 bool scsi_pass_through_and_check(scsi_cmnd_io
* iop
,
589 const char * msg
= "");
591 /// Always try READ CAPACITY(10) (rcap10) first but once we know
592 /// rcap16 is needed, use it instead.
593 void set_rcap16_first()
594 { rcap16_first
= true; }
596 bool use_rcap16() const
597 { return rcap16_first
; }
600 /// Hide/unhide SCSI interface.
601 void hide_scsi(bool hide
= true)
602 { m_scsi_ptr
= (!hide
? this : 0); }
604 /// Default constructor, registers device as SCSI.
606 : smart_device(never_called
),
608 { hide_scsi(false); }
615 /////////////////////////////////////////////////////////////////////////////
616 // NVMe specific interface
618 /// NVMe pass through input parameters
621 unsigned char opcode
; ///< Opcode (CDW0 07:00)
622 unsigned nsid
; ///< Namespace ID
623 unsigned cdw10
, cdw11
, cdw12
, cdw13
, cdw14
, cdw15
; ///< Cmd specific
625 void * buffer
; ///< Pointer to data buffer
626 unsigned size
; ///< Size of buffer
629 no_data
= 0x0, data_out
= 0x1, data_in
= 0x2, data_io
= 0x3
632 /// Get I/O direction from opcode
633 unsigned char direction() const
634 { return (opcode
& 0x3); }
636 // Prepare for DATA IN command
637 void set_data_in(unsigned char op
, void * buf
, unsigned sz
)
640 if (direction() != data_in
)
641 throw std::logic_error("invalid opcode for DATA IN");
647 : opcode(0), nsid(0),
648 cdw10(0), cdw11(0), cdw12(0), cdw13(0), cdw14(0), cdw15(0),
653 /// NVMe pass through output parameters
656 unsigned result
; ///< Command specific result (DW0)
657 unsigned short status
; ///< Status Field (DW3 31:17)
658 bool status_valid
; ///< true if status is valid
661 : result(0), status(0), status_valid(false)
665 /// NVMe device access
667 : virtual public /*extends*/ smart_device
670 /// NVMe pass through.
671 /// Return false on error.
672 virtual bool nvme_pass_through(const nvme_cmd_in
& in
, nvme_cmd_out
& out
) = 0;
674 /// Get namespace id.
675 unsigned get_nsid() const
679 /// Hide/unhide NVMe interface.
680 void hide_nvme(bool hide
= true)
681 { m_nvme_ptr
= (!hide
? this : 0); }
683 /// Constructor requires namespace ID, registers device as NVMe.
684 explicit nvme_device(unsigned nsid
)
685 : smart_device(never_called
),
687 { hide_nvme(false); }
689 /// Set namespace id.
690 /// Should be called in open() function if get_nsid() returns 0.
691 void set_nsid(unsigned nsid
)
694 /// Set last error number and message if pass-through returns NVMe error status.
695 /// Returns false always to allow use as a return expression.
696 bool set_nvme_err(nvme_cmd_out
& out
, unsigned status
, const char * msg
= 0);
703 /////////////////////////////////////////////////////////////////////////////
704 /// Smart pointer class for device pointers
707 class any_device_auto_ptr
710 typedef Dev device_type
;
712 /// Construct from optional pointer to device
713 /// and optional pointer to base device.
714 explicit any_device_auto_ptr(device_type
* dev
= 0,
715 smart_device
* base_dev
= 0)
716 : m_dev(dev
), m_base_dev(base_dev
) { }
718 /// Destructor deletes device object.
719 ~any_device_auto_ptr() throw()
722 /// Assign a new pointer.
723 /// Throws if a pointer is already assigned.
724 void operator=(device_type
* dev
)
731 /// Delete device object and clear the pointer.
735 if (m_base_dev
&& m_dev
->owns(m_base_dev
))
736 m_dev
->release(m_base_dev
);
742 /// Return the pointer and release ownership.
743 device_type
* release()
745 device_type
* dev
= m_dev
;
750 /// Replace the pointer.
751 /// Used to call dev->autodetect_open().
752 void replace(device_type
* dev
)
755 /// Return the pointer.
756 device_type
* get() const
759 /// Pointer dereferencing.
760 device_type
& operator*() const
763 /// Pointer dereferencing.
764 device_type
* operator->() const
767 /// For (ptr != 0) check.
768 operator bool() const
771 /// For (ptr == 0) check.
772 bool operator !() const
777 smart_device
* m_base_dev
;
780 { throw std::logic_error("any_device_auto_ptr: wrong usage"); }
782 // Prevent copy/assignment
783 any_device_auto_ptr(const any_device_auto_ptr
<Dev
> &);
784 void operator=(const any_device_auto_ptr
<Dev
> &);
787 typedef any_device_auto_ptr
<smart_device
> smart_device_auto_ptr
;
788 typedef any_device_auto_ptr
<ata_device
> ata_device_auto_ptr
;
789 typedef any_device_auto_ptr
<scsi_device
> scsi_device_auto_ptr
;
790 typedef any_device_auto_ptr
<nvme_device
> nvme_device_auto_ptr
;
793 /////////////////////////////////////////////////////////////////////////////
796 /// List of devices for DEVICESCAN
797 class smart_device_list
804 ~smart_device_list() throw()
806 for (unsigned i
= 0; i
< m_list
.size(); i
++)
811 unsigned size() const
812 { return m_list
.size(); }
817 for (unsigned i
= 0; i
< m_list
.size(); i
++)
823 void push_back(smart_device
* dev
)
824 { m_list
.push_back(dev
); }
826 void push_back(smart_device_auto_ptr
& dev
)
828 m_list
.push_back(dev
.get());
832 smart_device
* at(unsigned i
)
833 { return m_list
.at(i
); }
835 const smart_device
* at(unsigned i
) const
836 { return m_list
.at(i
); }
838 smart_device
* release(unsigned i
)
840 smart_device
* dev
= m_list
.at(i
);
845 void append(smart_device_list
& devlist
)
847 for (unsigned i
= 0; i
< devlist
.size(); i
++) {
848 smart_device
* dev
= devlist
.at(i
);
852 devlist
.m_list
.at(i
) = 0;
858 std::vector
<smart_device
*> m_list
;
860 // Prevent copy/assignment
861 smart_device_list(const smart_device_list
&);
862 void operator=(const smart_device_list
&);
866 /// List of types for DEVICESCAN
867 typedef std::vector
<std::string
> smart_devtype_list
;
870 /////////////////////////////////////////////////////////////////////////////
873 /// The platform interface abstraction
874 class smart_interface
877 /// Initialize platform interface and register with smi().
878 /// Must be implemented by platform module and register interface with set()
884 virtual ~smart_interface() throw()
887 /// Return info string about build host and/or OS version.
888 /// Default implementation returns SMARTMONTOOLS_BUILD_HOST.
889 virtual std::string
get_os_version_str();
891 /// Return valid args for device type option/directive.
892 /// Default implementation returns "ata, scsi, sat, usb*..."
893 /// concatenated with result from get_valid_custom_dev_types_str().
894 virtual std::string
get_valid_dev_types_str();
896 /// Return example string for program 'appname'.
897 /// Default implementation returns empty string.
898 /// For the migration of print_smartctl_examples(),
899 /// function is allowed to print examples to stdout.
900 /// TODO: Remove this hack.
901 virtual std::string
get_app_examples(const char * appname
);
903 /// Get microseconds since some unspecified starting point.
904 /// Used only for command duration measurements in debug outputs.
905 /// Returns -1 if unsupported.
906 /// Default implementation uses clock_gettime(), gettimeofday() or ftime().
907 virtual int64_t get_timer_usec();
909 /// Disable/Enable system auto standby/sleep mode.
910 /// Return false if unsupported or if system is running
912 /// Default implementation returns false.
913 virtual bool disable_system_auto_standby(bool disable
);
916 ///////////////////////////////////////////////
917 // Last error information
919 /// Get last error info struct.
920 const smart_device::error_info
& get_err() const
922 /// Get last error number.
923 int get_errno() const
925 /// Get last error message.
926 const char * get_errmsg() const
927 { return m_err
.msg
.c_str(); }
929 /// Set last error number and message.
930 /// Printf()-like formatting is supported.
931 /// Returns false always to allow use as a return expression.
932 bool set_err(int no
, const char * msg
, ...)
933 __attribute_format_printf(3, 4);
935 /// Set last error info struct.
936 bool set_err(const smart_device::error_info
& err
)
937 { m_err
= err
; return false; }
939 /// Clear last error info.
943 /// Set last error number and default message.
944 /// Message is retrieved from get_msg_for_errno(no).
945 bool set_err(int no
);
947 /// Set last error number and default message to any error_info.
948 /// Used by set_err(no).
949 bool set_err_var(smart_device::error_info
* err
, int no
);
951 /// Convert error number into message, used by set_err(no).
952 /// Default implementation returns strerror(no).
953 virtual const char * get_msg_for_errno(int no
);
955 ///////////////////////////////////////////////////////////////////////////
958 /// Return device object for device 'name' with some 'type'.
959 /// 'type' is 0 if not specified by user.
960 /// Return 0 on error.
961 /// Default implementation selects between ata, scsi and custom device.
962 virtual smart_device
* get_smart_device(const char * name
, const char * type
);
964 /// Fill 'devlist' with devices of some 'type' with device names
965 /// specified by some optional 'pattern'.
966 /// Use platform specific default if 'type' is empty or 0.
967 /// Return false on error.
968 /// Default implementation returns false;
969 virtual bool scan_smart_devices(smart_device_list
& devlist
, const char * type
,
970 const char * pattern
= 0);
972 /// Fill 'devlist' with devices of all 'types' with device names
973 /// specified by some optional 'pattern'.
974 /// Use platform specific default if 'types' is empty.
975 /// Return false on error.
976 /// Default implementation calls above function for all types
977 /// and concatenates the results.
978 virtual bool scan_smart_devices(smart_device_list
& devlist
,
979 const smart_devtype_list
& types
, const char * pattern
= 0);
982 /// Return standard ATA device.
983 virtual ata_device
* get_ata_device(const char * name
, const char * type
) = 0;
985 /// Return standard SCSI device.
986 virtual scsi_device
* get_scsi_device(const char * name
, const char * type
) = 0;
988 /// Return standard NVMe device.
989 /// Default implementation returns 0.
990 virtual nvme_device
* get_nvme_device(const char * name
, const char * type
,
993 /// Autodetect device if no device type specified.
994 virtual smart_device
* autodetect_smart_device(const char * name
) = 0;
996 /// Return device for platform specific 'type'.
997 /// Default implementation returns 0.
998 virtual smart_device
* get_custom_smart_device(const char * name
, const char * type
);
1000 /// Return valid 'type' args accepted by above.
1001 /// This is called in get_valid_dev_types_str().
1002 /// Default implementation returns empty string.
1003 virtual std::string
get_valid_custom_dev_types_str();
1005 /// Return ATA->SCSI of NVMe->SCSI filter for a SAT, SNT or USB 'type'.
1006 /// Uses get_sat_device and get_snt_device.
1007 /// Return 0 and delete 'scsidev' on error.
1008 virtual smart_device
* get_scsi_passthrough_device(const char * type
, scsi_device
* scsidev
);
1010 /// Return ATA->SCSI filter for a SAT or USB 'type'.
1011 /// Device 'scsidev' is used for SCSI access.
1012 /// Return 0 and delete 'scsidev' on error.
1013 /// Override only if platform needs special handling.
1014 virtual ata_device
* get_sat_device(const char * type
, scsi_device
* scsidev
);
1015 //{ implemented in scsiata.cpp }
1017 /// Return NVMe->SCSI filter for a SNT or USB 'type'.
1018 /// Device 'scsidev' is used for SCSI access.
1019 /// Return 0 and delete 'scsidev' on error.
1020 /// Override only if platform needs special handling.
1021 virtual nvme_device
* get_snt_device(const char * type
, scsi_device
* scsidev
);
1022 //{ implemented in scsinvme.cpp }
1025 /// Try to detect a SAT device behind a SCSI interface.
1026 /// Inquiry data can be passed if available.
1027 /// Return appropriate device if yes, otherwise 0.
1028 /// Override only if platform needs special handling.
1029 virtual ata_device
* autodetect_sat_device(scsi_device
* scsidev
,
1030 const unsigned char * inqdata
, unsigned inqsize
);
1031 //{ implemented in scsiata.cpp }
1033 /// Get type name for USB device with known VENDOR:PRODUCT ID.
1034 /// Return name if device known and supported, otherwise 0.
1035 virtual const char * get_usb_dev_type_by_id(int vendor_id
, int product_id
,
1037 //{ implemented in scsiata.cpp }
1040 /// Set interface to use, must be called from init().
1041 static void set(smart_interface
* intf
)
1042 { s_instance
= intf
; }
1046 smart_device::error_info m_err
;
1048 friend smart_interface
* smi(); // below
1049 static smart_interface
* s_instance
; ///< Pointer to the interface object.
1051 // Prevent copy/assignment
1052 smart_interface(const smart_interface
&);
1053 void operator=(const smart_interface
&);
1057 /////////////////////////////////////////////////////////////////////////////
1060 /// Global access to the (usually singleton) smart_interface
1061 inline smart_interface
* smi()
1062 { return smart_interface::s_instance
; }
1064 /////////////////////////////////////////////////////////////////////////////
1066 #endif // DEV_INTERFACE_H