4 * Home page of code is: http://smartmontools.sourceforge.net
6 * Copyright (C) 2008-12 Christian Franke <smartmontools-support@lists.sourceforge.net>
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)
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/>.
18 #ifndef DEV_INTERFACE_H
19 #define DEV_INTERFACE_H
21 #define DEV_INTERFACE_H_CVSID "$Id: dev_interface.h 3663 2012-10-24 20:35:55Z chrfranke $\n"
29 /////////////////////////////////////////////////////////////////////////////
30 // Common functionality for all device types
32 // Forward declarations
33 class smart_interface
;
37 /// Base class for all devices
42 /// Device info strings
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
)
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
57 /// Error (number,message) pair
59 explicit error_info(int n
= 0)
61 error_info(int n
, const char * m
)
64 { no
= 0; msg
.erase(); }
66 int no
; ///< Error number
67 std::string msg
; ///< Error message
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
);
77 /// Dummy enum for dummy constructor.
78 enum do_not_use_in_implementation_classes
{ never_called
};
79 /// Dummy constructor for abstract classes.
80 /// Must never be called in implementation classes.
81 smart_device(do_not_use_in_implementation_classes
);
84 virtual ~smart_device() throw();
88 ///////////////////////////////////////////////
89 // Dynamic downcasts to actual device flavor
91 /// Return true if ATA device
93 { return !!m_ata_ptr
; }
94 /// Return true if SCSI device
96 { return !!m_scsi_ptr
; }
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.
105 scsi_device
* to_scsi()
106 { return m_scsi_ptr
; }
107 /// Downcast to SCSI device (const).
108 const scsi_device
* to_scsi() const
109 { return m_scsi_ptr
; }
111 ///////////////////////////////////////////////
112 // Device information
114 /// Get device info struct.
115 const device_info
& get_info() const
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(); }
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(); }
132 /// R/W access to device info struct.
133 device_info
& set_info()
137 ///////////////////////////////////////////////
138 // Last error information
140 /// Get last error info struct.
141 const error_info
& get_err() const
143 /// Get last error number.
144 int get_errno() const
146 /// Get last error message.
147 const char * get_errmsg() const
148 { return m_err
.msg
.c_str(); }
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;
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
, ...)
158 __attribute_format_printf(3, 4);
160 /// Set last error info struct.
161 bool set_err(const error_info
& err
)
162 { m_err
= err
; return false; }
164 /// Clear last error info.
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
);
174 ///////////////////////////////////////////////
176 // Must be implemented in derived class
178 /// Return true if device is open.
179 virtual bool is_open() const = 0;
181 /// Open device, return false on error.
182 virtual bool open() = 0;
184 /// Close device, return false on error.
185 virtual bool close() = 0;
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();
193 ///////////////////////////////////////////////
194 // Support for tunnelled devices
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;
200 /// Release ownership of other device.
201 /// Default implementation does nothing.
202 virtual void release(const smart_device
* dev
);
205 /// Get interface which produced this object.
206 smart_interface
* smi()
208 /// Get interface which produced this object (const).
209 const smart_interface
* smi() const
214 smart_interface
* m_intf
;
218 // Pointers for to_ata(), to_scsi(),
219 // set by ATA/SCSI interface classes.
220 friend class ata_device
;
221 ata_device
* m_ata_ptr
;
222 friend class scsi_device
;
223 scsi_device
* m_scsi_ptr
;
225 // Prevent copy/assigment
226 smart_device(const smart_device
&);
227 void operator=(const smart_device
&);
231 /////////////////////////////////////////////////////////////////////////////
232 // ATA specific interface
234 /// ATA register value and info whether it has ever been set
235 // (Automatically set by first assignment)
240 : m_val(0x00), m_is_set(false) { }
242 ata_register
& operator=(unsigned char x
)
243 { m_val
= x
; m_is_set
= true; return * this; }
245 unsigned char val() const
247 operator unsigned char() const
254 unsigned char m_val
; ///< Register value
255 bool m_is_set
; ///< true if set
258 /// ATA Input registers (for 28-bit commands)
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
270 /// Return true if any register is set
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()); }
277 /// ATA Output registers (for 28-bit commands)
281 ata_register sector_count
;
282 ata_register lba_low
;
283 ata_register lba_mid
;
284 ata_register lba_high
;
288 /// Return true if any register is set
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()); }
296 /// 16-bit alias to a 8-bit ATA register pair.
297 class ata_reg_alias_16
300 ata_reg_alias_16(ata_register
& lo
, ata_register
& hi
)
301 : m_lo(lo
), m_hi(hi
) { }
303 ata_reg_alias_16
& operator=(unsigned short x
)
304 { m_lo
= (unsigned char) x
;
305 m_hi
= (unsigned char)(x
>> 8);
308 unsigned short val() const
309 { return m_lo
| (m_hi
<< 8); }
310 operator unsigned short() const
311 { return m_lo
| (m_hi
<< 8); }
314 ata_register
& m_lo
, & m_hi
;
316 // References must not be copied.
317 ata_reg_alias_16(const ata_reg_alias_16
&);
318 void operator=(const ata_reg_alias_16
&);
322 /// 48-bit alias to six 8-bit ATA registers (for LBA).
323 class ata_reg_alias_48
326 ata_reg_alias_48(ata_register
& ll
, ata_register
& lm
, ata_register
& lh
,
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
)
332 ata_reg_alias_48
& operator=(uint64_t x
)
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);
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));
353 operator uint64_t() const
357 ata_register
& m_ll
, & m_lm
, & m_lh
,
358 & m_hl
, & m_hm
, & m_hh
;
360 // References must not be copied.
361 ata_reg_alias_48(const ata_reg_alias_48
&);
362 void operator=(const ata_reg_alias_48
&);
366 /// ATA Input registers for 48-bit commands
367 // See section 4.14 of T13/1532D Volume 1 Revision 4b
369 // Uses ATA-6/7 method to specify 16-bit registers as
370 // recent (low byte) and previous (high byte) content of
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.)
377 struct ata_in_regs_48bit
378 : public ata_in_regs
// "most recently written" registers
380 ata_in_regs prev
; ///< "previous content"
382 // 16-bit aliases for above pair.
383 ata_reg_alias_16 features_16
;
384 ata_reg_alias_16 sector_count_16
;
385 ata_reg_alias_16 lba_low_16
;
386 ata_reg_alias_16 lba_mid_16
;
387 ata_reg_alias_16 lba_high_16
;
389 // 48-bit alias to all 8-bit LBA registers.
390 ata_reg_alias_48 lba_48
;
392 /// Return true if 48-bit command
393 bool is_48bit_cmd() const
394 { return prev
.is_set(); }
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
); }
405 /// ATA Output registers for 48-bit commands
406 struct ata_out_regs_48bit
407 : public ata_out_regs
// read with HOB=0
409 ata_out_regs prev
; ///< read with HOB=1
411 // 16-bit aliases for above pair.
412 ata_reg_alias_16 sector_count_16
;
413 ata_reg_alias_16 lba_low_16
;
414 ata_reg_alias_16 lba_mid_16
;
415 ata_reg_alias_16 lba_high_16
;
417 // 48-bit alias to all 8-bit LBA registers.
418 ata_reg_alias_48 lba_48
;
420 ata_out_regs_48bit();
424 /// Flags for each ATA output register
425 struct ata_out_regs_flags
427 bool error
, sector_count
, lba_low
, lba_mid
, lba_high
, device
, status
;
429 /// Return true if any flag is set.
431 { return ( error
|| sector_count
|| lba_low
432 || lba_mid
|| lba_high
|| device
|| status
); }
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) { }
441 /// ATA pass through input parameters
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
450 /// Prepare for 28-bit DATA IN command
451 void set_data_in(void * buf
, unsigned nsectors
)
454 in_regs
.sector_count
= nsectors
;
456 size
= nsectors
* 512;
459 /// Prepare for 28-bit DATA OUT command
460 void set_data_out(const void * buf
, unsigned nsectors
)
462 buffer
= const_cast<void *>(buf
);
463 in_regs
.sector_count
= nsectors
;
464 direction
= data_out
;
465 size
= nsectors
* 512;
468 /// Prepare for 48-bit DATA IN command
469 void set_data_in_48bit(void * buf
, unsigned nsectors
)
472 // Note: This also sets 'in_regs.is_48bit_cmd()'
473 in_regs
.sector_count_16
= nsectors
;
475 size
= nsectors
* 512;
481 /// ATA pass through output parameters
484 ata_out_regs_48bit out_regs
; ///< Output registers
489 /// ATA device access
491 : virtual public /*extends*/ smart_device
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;
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
);
504 /// Return true if OS caches ATA identify sector.
505 /// Default implementation returns false.
506 virtual bool ata_identify_is_cached() const;
509 /// Flags for ata_cmd_is_supported().
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
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);
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)
532 return ata_cmd_is_supported(in
,
533 (data_out_support
? supports_data_out
: 0) |
534 supports_output_regs
|
535 (multi_sector_support
? supports_multi_sector
: 0) |
536 (ata_48bit_support
? supports_48bit
: 0));
539 /// Hide/unhide ATA interface.
540 void hide_ata(bool hide
= true)
541 { m_ata_ptr
= (!hide
? this : 0); }
543 /// Default constructor, registers device as ATA.
545 : smart_device(never_called
)
550 /////////////////////////////////////////////////////////////////////////////
551 // SCSI specific interface
555 /// SCSI device access
557 : virtual public /*extends*/ smart_device
560 /// SCSI pass through.
561 /// Returns false on error.
562 virtual bool scsi_pass_through(scsi_cmnd_io
* iop
) = 0;
565 /// Hide/unhide SCSI interface.
566 void hide_scsi(bool hide
= true)
567 { m_scsi_ptr
= (!hide
? this : 0); }
569 /// Default constructor, registers device as SCSI.
571 : smart_device(never_called
)
572 { hide_scsi(false); }
576 /////////////////////////////////////////////////////////////////////////////
577 /// Smart pointer class for device pointers
580 class any_device_auto_ptr
583 typedef Dev device_type
;
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
) { }
591 /// Destructor deletes device object.
592 ~any_device_auto_ptr() throw()
595 /// Assign a new pointer.
596 /// Throws if a pointer is already assigned.
597 void operator=(device_type
* dev
)
604 /// Delete device object and clear the pointer.
608 if (m_base_dev
&& m_dev
->owns(m_base_dev
))
609 m_dev
->release(m_base_dev
);
615 /// Return the pointer and release ownership.
616 device_type
* release()
618 device_type
* dev
= m_dev
;
623 /// Replace the pointer.
624 /// Used to call dev->autodetect_open().
625 void replace(device_type
* dev
)
628 /// Return the pointer.
629 device_type
* get() const
632 /// Pointer dereferencing.
633 device_type
& operator*() const
636 /// Pointer dereferencing.
637 device_type
* operator->() const
640 /// For (ptr != 0) check.
641 operator bool() const
644 /// For (ptr == 0) check.
645 bool operator !() const
650 smart_device
* m_base_dev
;
653 { throw std::logic_error("any_device_auto_ptr: wrong usage"); }
655 // Prevent copy/assignment
656 any_device_auto_ptr(const any_device_auto_ptr
<Dev
> &);
657 void operator=(const any_device_auto_ptr
<Dev
> &);
660 typedef any_device_auto_ptr
<smart_device
> smart_device_auto_ptr
;
661 typedef any_device_auto_ptr
<ata_device
> ata_device_auto_ptr
;
662 typedef any_device_auto_ptr
<scsi_device
> scsi_device_auto_ptr
;
665 /////////////////////////////////////////////////////////////////////////////
668 /// List of devices for DEVICESCAN
669 class smart_device_list
676 ~smart_device_list() throw()
678 for (unsigned i
= 0; i
< m_list
.size(); i
++)
683 unsigned size() const
684 { return m_list
.size(); }
689 for (unsigned i
= 0; i
< m_list
.size(); i
++)
695 void push_back(smart_device
* dev
)
696 { m_list
.push_back(dev
); }
698 void push_back(smart_device_auto_ptr
& dev
)
700 m_list
.push_back(dev
.get());
704 smart_device
* at(unsigned i
)
705 { return m_list
.at(i
); }
707 const smart_device
* at(unsigned i
) const
708 { return m_list
.at(i
); }
710 smart_device
* release(unsigned i
)
712 smart_device
* dev
= m_list
.at(i
);
719 std::vector
<smart_device
*> m_list
;
721 // Prevent copy/assigment
722 smart_device_list(const smart_device_list
&);
723 void operator=(const smart_device_list
&);
727 /////////////////////////////////////////////////////////////////////////////
730 /// The platform interface abstraction
731 class smart_interface
734 /// Initialize platform interface and register with smi().
735 /// Must be implemented by platform module and register interface with set()
741 virtual ~smart_interface() throw()
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();
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();
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
);
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();
766 /// Disable/Enable system auto standby/sleep mode.
767 /// Return false if unsupported or if system is running
769 /// Default implementation returns false.
770 virtual bool disable_system_auto_standby(bool disable
);
773 ///////////////////////////////////////////////
774 // Last error information
776 /// Get last error info struct.
777 const smart_device::error_info
& get_err() const
779 /// Get last error number.
780 int get_errno() const
782 /// Get last error message.
783 const char * get_errmsg() const
784 { return m_err
.msg
.c_str(); }
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
, ...)
790 __attribute_format_printf(3, 4);
792 /// Set last error info struct.
793 bool set_err(const smart_device::error_info
& err
)
794 { m_err
= err
; return false; }
796 /// Clear last error info.
800 /// Set last error number and default message.
801 /// Message is retrieved from get_msg_for_errno(no).
802 bool set_err(int no
);
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
);
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
);
812 ///////////////////////////////////////////////////////////////////////////
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
);
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;
828 /// Return standard ATA device.
829 virtual ata_device
* get_ata_device(const char * name
, const char * type
) = 0;
831 /// Return standard SCSI device.
832 virtual scsi_device
* get_scsi_device(const char * name
, const char * type
) = 0;
834 /// Autodetect device if no device type specified.
835 virtual smart_device
* autodetect_smart_device(const char * name
) = 0;
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
);
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();
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 }
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 }
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
,
864 //{ implemented in scsiata.cpp }
867 /// Set interface to use, must be called from init().
868 static void set(smart_interface
* intf
)
869 { s_instance
= intf
; }
873 smart_device::error_info m_err
;
875 friend smart_interface
* smi(); // below
876 static smart_interface
* s_instance
; ///< Pointer to the interface object.
878 // Prevent copy/assigment
879 smart_interface(const smart_interface
&);
880 void operator=(const smart_interface
&);
884 /////////////////////////////////////////////////////////////////////////////
887 /// Global access to the (usually singleton) smart_interface
888 inline smart_interface
* smi()
889 { return smart_interface::s_instance
; }
891 /////////////////////////////////////////////////////////////////////////////
893 #endif // DEV_INTERFACE_H