4 * Home page of code is: http://smartmontools.sourceforge.net
6 * Copyright (C) 2008-11 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 3256 2011-02-08 22:13:41Z chrfranke $\n"
27 #if !defined(__GNUC__) && !defined(__attribute__)
28 #define __attribute__(x) /**/
31 #ifdef _MSC_VER // Disable MSVC warning
32 #pragma warning(disable:4250) // 'class1' : inherits 'class2::member' via dominance
35 /////////////////////////////////////////////////////////////////////////////
36 // Common functionality for all device types
38 // Forward declarations
39 class smart_interface
;
43 /// Base class for all devices
48 /// Device info strings
52 device_info(const char * d_name
, const char * d_type
, const char * r_type
)
53 : dev_name(d_name
), info_name(d_name
),
54 dev_type(d_type
), req_type(r_type
)
57 std::string dev_name
; ///< Device (path)name
58 std::string info_name
; ///< Informal name
59 std::string dev_type
; ///< Actual device type
60 std::string req_type
; ///< Device type requested by user, empty if none
63 /// Error (number,message) pair
65 explicit error_info(int n
= 0)
67 error_info(int n
, const char * m
)
70 { no
= 0; msg
.erase(); }
72 int no
; ///< Error number
73 std::string msg
; ///< Error message
78 /// Constructor to init interface and device info.
79 /// Must be called in implementation classes.
80 smart_device(smart_interface
* intf
, const char * dev_name
,
81 const char * dev_type
, const char * req_type
);
83 /// Dummy enum for dummy constructor.
84 enum do_not_use_in_implementation_classes
{ never_called
};
85 /// Dummy constructor for abstract classes.
86 /// Must never be called in implementation classes.
87 smart_device(do_not_use_in_implementation_classes
);
90 virtual ~smart_device() throw();
94 ///////////////////////////////////////////////
95 // Dynamic downcasts to actual device flavor
97 /// Return true if ATA device
99 { return !!m_ata_ptr
; }
100 /// Return true if SCSI device
102 { return !!m_scsi_ptr
; }
104 /// Downcast to ATA device.
105 ata_device
* to_ata()
106 { return m_ata_ptr
; }
107 /// Downcast to ATA device (const).
108 const ata_device
* to_ata() const
109 { return m_ata_ptr
; }
110 /// Downcast to SCSI device.
111 scsi_device
* to_scsi()
112 { return m_scsi_ptr
; }
113 /// Downcast to SCSI device (const).
114 const scsi_device
* to_scsi() const
115 { return m_scsi_ptr
; }
117 ///////////////////////////////////////////////
118 // Device information
120 /// Get device info struct.
121 const device_info
& get_info() const
124 /// Get device (path)name.
125 const char * get_dev_name() const
126 { return m_info
.dev_name
.c_str(); }
127 /// Get informal name.
128 const char * get_info_name() const
129 { return m_info
.info_name
.c_str(); }
131 const char * get_dev_type() const
132 { return m_info
.dev_type
.c_str(); }
133 /// Get type requested by user, empty if none.
134 const char * get_req_type() const
135 { return m_info
.req_type
.c_str(); }
138 /// R/W access to device info struct.
139 device_info
& set_info()
143 ///////////////////////////////////////////////
144 // Last error information
146 /// Get last error info struct.
147 const error_info
& get_err() const
149 /// Get last error number.
150 int get_errno() const
152 /// Get last error message.
153 const char * get_errmsg() const
154 { return m_err
.msg
.c_str(); }
156 /// Set last error number and message.
157 /// Printf()-like formatting is supported.
158 /// Returns false always to allow use as a return expression.
159 bool set_err(int no
, const char * msg
, ...)
160 __attribute__ ((format (printf
, 3, 4)));
162 /// Set last error info struct.
163 bool set_err(const error_info
& err
)
164 { m_err
= err
; return false; }
166 /// Clear last error info.
170 /// Set last error number and default message.
171 /// Message is retrieved from interface's get_msg_for_errno(no).
172 bool set_err(int no
);
176 ///////////////////////////////////////////////
178 // Must be implemented in derived class
180 /// Return true if device is open.
181 virtual bool is_open() const = 0;
183 /// Open device, return false on error.
184 virtual bool open() = 0;
186 /// Close device, return false on error.
187 virtual bool close() = 0;
189 /// Open device with autodetection support.
190 /// May return another device for further access.
191 /// In this case, the original pointer is no longer valid.
192 /// Default Implementation calls 'open()' and returns 'this'.
193 virtual smart_device
* autodetect_open();
195 ///////////////////////////////////////////////
196 // Support for tunnelled devices
198 /// Return true if other device is owned by this device.
199 /// Default implementation returns false.
200 virtual bool owns(const smart_device
* dev
) const;
202 /// Release ownership of other device.
203 /// Default implementation does nothing.
204 virtual void release(const smart_device
* dev
);
207 /// Set dynamic downcast for ATA
208 void this_is_ata(ata_device
* ata
);
211 /// Set dynamic downcast for SCSI
212 void this_is_scsi(scsi_device
* scsi
);
215 /// Get interface which produced this object.
216 smart_interface
* smi()
218 /// Get interface which produced this object (const).
219 const smart_interface
* smi() const
224 smart_interface
* m_intf
;
226 ata_device
* m_ata_ptr
;
227 scsi_device
* m_scsi_ptr
;
230 // Prevent copy/assigment
231 smart_device(const smart_device
&);
232 void operator=(const smart_device
&);
236 /////////////////////////////////////////////////////////////////////////////
237 // ATA specific interface
239 /// ATA register value and info whether it has ever been set
240 // (Automatically set by first assignment)
245 : m_val(0x00), m_is_set(false) { }
247 ata_register
& operator=(unsigned char x
)
248 { m_val
= x
; m_is_set
= true; return * this; }
250 unsigned char val() const
252 operator unsigned char() const
259 unsigned char m_val
; ///< Register value
260 bool m_is_set
; ///< true if set
263 /// ATA Input registers (for 28-bit commands)
266 // ATA-6/7 register names // ATA-3/4/5 // ATA-8
267 ata_register features
; // features // features
268 ata_register sector_count
; // sector count // count
269 ata_register lba_low
; // sector number // ]
270 ata_register lba_mid
; // cylinder low // ] lba
271 ata_register lba_high
; // cylinder high // ]
272 ata_register device
; // device/head // device
273 ata_register command
; // command // command
275 /// Return true if any register is set
277 { return (features
.is_set() || sector_count
.is_set()
278 || lba_low
.is_set() || lba_mid
.is_set() || lba_high
.is_set()
279 || device
.is_set() || command
.is_set()); }
282 /// ATA Output registers (for 28-bit commands)
286 ata_register sector_count
;
287 ata_register lba_low
;
288 ata_register lba_mid
;
289 ata_register lba_high
;
293 /// Return true if any register is set
295 { return (error
.is_set() || sector_count
.is_set()
296 || lba_low
.is_set() || lba_mid
.is_set() || lba_high
.is_set()
297 || device
.is_set() || status
.is_set()); }
301 /// 16-bit alias to a 8-bit ATA register pair.
302 class ata_reg_alias_16
305 ata_reg_alias_16(ata_register
& lo
, ata_register
& hi
)
306 : m_lo(lo
), m_hi(hi
) { }
308 ata_reg_alias_16
& operator=(unsigned short x
)
309 { m_lo
= (unsigned char) x
;
310 m_hi
= (unsigned char)(x
>> 8);
313 unsigned short val() const
314 { return m_lo
| (m_hi
<< 8); }
315 operator unsigned short() const
316 { return m_lo
| (m_hi
<< 8); }
319 ata_register
& m_lo
, & m_hi
;
321 // References must not be copied.
322 ata_reg_alias_16(const ata_reg_alias_16
&);
323 void operator=(const ata_reg_alias_16
&);
327 /// 48-bit alias to six 8-bit ATA registers (for LBA).
328 class ata_reg_alias_48
331 ata_reg_alias_48(ata_register
& ll
, ata_register
& lm
, ata_register
& lh
,
332 ata_register
& hl
, ata_register
& hm
, ata_register
& hh
)
333 : m_ll(ll
), m_lm(lm
), m_lh(lh
),
334 m_hl(hl
), m_hm(hm
), m_hh(hh
)
337 ata_reg_alias_48
& operator=(uint64_t x
)
339 m_ll
= (unsigned char) x
;
340 m_lm
= (unsigned char)(x
>> 8);
341 m_lh
= (unsigned char)(x
>> 16);
342 m_hl
= (unsigned char)(x
>> 24);
343 m_hm
= (unsigned char)(x
>> 32);
344 m_hh
= (unsigned char)(x
>> 40);
350 return ( (unsigned)m_ll
351 | ((unsigned)m_lm
<< 8)
352 | ((unsigned)m_lh
<< 16)
353 | ((unsigned)m_hl
<< 24)
354 | ((uint64_t)m_hm
<< 32)
355 | ((uint64_t)m_hh
<< 40));
358 operator uint64_t() const
362 ata_register
& m_ll
, & m_lm
, & m_lh
,
363 & m_hl
, & m_hm
, & m_hh
;
365 // References must not be copied.
366 ata_reg_alias_48(const ata_reg_alias_48
&);
367 void operator=(const ata_reg_alias_48
&);
371 /// ATA Input registers for 48-bit commands
372 // See section 4.14 of T13/1532D Volume 1 Revision 4b
374 // Uses ATA-6/7 method to specify 16-bit registers as
375 // recent (low byte) and previous (high byte) content of
378 // (ATA-8 ACS does not longer follow this scheme, it uses
379 // abstract registers with sufficient size and leaves the
380 // actual mapping to the transport layer.)
382 struct ata_in_regs_48bit
383 : public ata_in_regs
// "most recently written" registers
385 ata_in_regs prev
; ///< "previous content"
387 // 16-bit aliases for above pair.
388 ata_reg_alias_16 features_16
;
389 ata_reg_alias_16 sector_count_16
;
390 ata_reg_alias_16 lba_low_16
;
391 ata_reg_alias_16 lba_mid_16
;
392 ata_reg_alias_16 lba_high_16
;
394 // 48-bit alias to all 8-bit LBA registers.
395 ata_reg_alias_48 lba_48
;
397 /// Return true if 48-bit command
398 bool is_48bit_cmd() const
399 { return prev
.is_set(); }
401 /// Return true if 48-bit command with any nonzero high byte
402 bool is_real_48bit_cmd() const
403 { return ( prev
.features
|| prev
.sector_count
404 || prev
.lba_low
|| prev
.lba_mid
|| prev
.lba_high
); }
410 /// ATA Output registers for 48-bit commands
411 struct ata_out_regs_48bit
412 : public ata_out_regs
// read with HOB=0
414 ata_out_regs prev
; ///< read with HOB=1
416 // 16-bit aliases for above pair.
417 ata_reg_alias_16 sector_count_16
;
418 ata_reg_alias_16 lba_low_16
;
419 ata_reg_alias_16 lba_mid_16
;
420 ata_reg_alias_16 lba_high_16
;
422 // 48-bit alias to all 8-bit LBA registers.
423 ata_reg_alias_48 lba_48
;
425 ata_out_regs_48bit();
429 /// Flags for each ATA output register
430 struct ata_out_regs_flags
432 bool error
, sector_count
, lba_low
, lba_mid
, lba_high
, device
, status
;
434 /// Return true if any flag is set.
436 { return ( error
|| sector_count
|| lba_low
437 || lba_mid
|| lba_high
|| device
|| status
); }
439 /// Default constructor clears all flags.
441 : error(false), sector_count(false), lba_low(false), lba_mid(false),
442 lba_high(false), device(false), status(false) { }
446 /// ATA pass through input parameters
449 ata_in_regs_48bit in_regs
; ///< Input registers
450 ata_out_regs_flags out_needed
; ///< True if output register value needed
451 enum { no_data
= 0, data_in
, data_out
} direction
; ///< I/O direction
452 void * buffer
; ///< Pointer to data buffer
453 unsigned size
; ///< Size of buffer
455 /// Prepare for 28-bit DATA IN command
456 void set_data_in(void * buf
, unsigned nsectors
)
459 in_regs
.sector_count
= nsectors
;
461 size
= nsectors
* 512;
464 /// Prepare for 28-bit DATA OUT command
465 void set_data_out(const void * buf
, unsigned nsectors
)
467 buffer
= const_cast<void *>(buf
);
468 in_regs
.sector_count
= nsectors
;
469 direction
= data_out
;
470 size
= nsectors
* 512;
473 /// Prepare for 48-bit DATA IN command
474 void set_data_in_48bit(void * buf
, unsigned nsectors
)
477 // Note: This also sets 'in_regs.is_48bit_cmd()'
478 in_regs
.sector_count_16
= nsectors
;
480 size
= nsectors
* 512;
486 /// ATA pass through output parameters
489 ata_out_regs_48bit out_regs
; ///< Output registers
494 /// ATA device access
496 : virtual public /*extends*/ smart_device
499 /// ATA pass through.
500 /// Return false on error.
501 /// Must be implemented in derived class.
502 virtual bool ata_pass_through(const ata_cmd_in
& in
, ata_cmd_out
& out
) = 0;
504 /// ATA pass through without output registers.
505 /// Return false on error.
506 /// Calls ata_pass_through(in, dummy), cannot be reimplemented.
507 bool ata_pass_through(const ata_cmd_in
& in
);
509 /// Return true if OS caches ATA identify sector.
510 /// Default implementation returns false.
511 virtual bool ata_identify_is_cached() const;
514 /// Check command input parameters.
515 /// Calls set_err(...) accordingly.
516 bool ata_cmd_is_ok(const ata_cmd_in
& in
,
517 bool data_out_support
= false,
518 bool multi_sector_support
= false,
519 bool ata_48bit_support
= false);
521 /// Default constructor, registers device as ATA.
523 : smart_device(never_called
)
524 { this_is_ata(this); }
528 /////////////////////////////////////////////////////////////////////////////
529 // SCSI specific interface
533 /// SCSI device access
535 : virtual public /*extends*/ smart_device
538 /// SCSI pass through.
539 /// Returns false on error.
540 virtual bool scsi_pass_through(scsi_cmnd_io
* iop
) = 0;
543 /// Default constructor, registers device as SCSI.
545 : smart_device(never_called
)
546 { this_is_scsi(this); }
550 /////////////////////////////////////////////////////////////////////////////
552 // Set dynamic downcasts
553 // Note that due to virtual inheritance,
554 // (ata == this) does not imply ((void*)ata == (void*)this))
556 inline void smart_device::this_is_ata(ata_device
* ata
)
558 m_ata_ptr
= (ata
== this ? ata
: 0);
561 inline void smart_device::this_is_scsi(scsi_device
* scsi
)
563 m_scsi_ptr
= (scsi
== this ? scsi
: 0);
567 /////////////////////////////////////////////////////////////////////////////
568 /// Smart pointer class for device pointers
571 class any_device_auto_ptr
574 typedef Dev device_type
;
576 /// Construct from optional pointer to device
577 /// and optional pointer to base device.
578 explicit any_device_auto_ptr(device_type
* dev
= 0,
579 smart_device
* base_dev
= 0)
580 : m_dev(dev
), m_base_dev(base_dev
) { }
582 /// Destructor deletes device object.
583 ~any_device_auto_ptr() throw()
586 /// Assign a new pointer.
587 /// Throws if a pointer is already assigned.
588 void operator=(device_type
* dev
)
595 /// Delete device object and clear the pointer.
599 if (m_base_dev
&& m_dev
->owns(m_base_dev
))
600 m_dev
->release(m_base_dev
);
606 /// Return the pointer and release ownership.
607 device_type
* release()
609 device_type
* dev
= m_dev
;
614 /// Replace the pointer.
615 /// Used to call dev->autodetect_open().
616 void replace(device_type
* dev
)
619 /// Return the pointer.
620 device_type
* get() const
623 /// Pointer dereferencing.
624 device_type
& operator*() const
627 /// Pointer dereferencing.
628 device_type
* operator->() const
631 /// For (ptr != 0) check.
632 operator bool() const
635 /// For (ptr == 0) check.
636 bool operator !() const
641 smart_device
* m_base_dev
;
644 { throw std::logic_error("any_device_auto_ptr: wrong usage"); }
646 // Prevent copy/assignment
647 any_device_auto_ptr(const any_device_auto_ptr
<Dev
> &);
648 void operator=(const any_device_auto_ptr
<Dev
> &);
651 typedef any_device_auto_ptr
<smart_device
> smart_device_auto_ptr
;
652 typedef any_device_auto_ptr
<ata_device
> ata_device_auto_ptr
;
653 typedef any_device_auto_ptr
<scsi_device
> scsi_device_auto_ptr
;
656 /////////////////////////////////////////////////////////////////////////////
659 /// List of devices for DEVICESCAN
660 class smart_device_list
667 ~smart_device_list() throw()
669 for (unsigned i
= 0; i
< m_list
.size(); i
++)
674 unsigned size() const
675 { return m_list
.size(); }
680 for (unsigned i
= 0; i
< m_list
.size(); i
++)
686 void push_back(smart_device
* dev
)
687 { m_list
.push_back(dev
); }
689 void push_back(smart_device_auto_ptr
& dev
)
691 m_list
.push_back(dev
.get());
695 smart_device
* at(unsigned i
)
696 { return m_list
.at(i
); }
698 const smart_device
* at(unsigned i
) const
699 { return m_list
.at(i
); }
701 smart_device
* release(unsigned i
)
703 smart_device
* dev
= m_list
.at(i
);
710 std::vector
<smart_device
*> m_list
;
712 // Prevent copy/assigment
713 smart_device_list(const smart_device_list
&);
714 void operator=(const smart_device_list
&);
718 /////////////////////////////////////////////////////////////////////////////
721 /// The platform interface abstraction
722 class smart_interface
725 /// Initialize platform interface and register with smi().
726 /// Must be implemented by platform module and register interface with set()
732 virtual ~smart_interface() throw()
735 /// Return info string about build host and/or OS version.
736 /// Default implementation returns SMARTMONTOOLS_BUILD_HOST.
737 virtual std::string
get_os_version_str();
739 /// Return valid args for device type option/directive.
740 /// Default implementation returns "ata, scsi, sat, usb*..."
741 /// concatenated with result from get_valid_custom_dev_types_str().
742 virtual std::string
get_valid_dev_types_str();
744 /// Return example string for program 'appname'.
745 /// Default implementation returns empty string.
746 /// For the migration of print_smartctl_examples(),
747 /// function is allowed to print examples to stdout.
748 /// TODO: Remove this hack.
749 virtual std::string
get_app_examples(const char * appname
);
751 ///////////////////////////////////////////////
752 // Last error information
754 /// Get last error info struct.
755 const smart_device::error_info
& get_err() const
757 /// Get last error number.
758 int get_errno() const
760 /// Get last error message.
761 const char * get_errmsg() const
762 { return m_err
.msg
.c_str(); }
764 /// Set last error number and message.
765 /// Printf()-like formatting is supported.
766 void set_err(int no
, const char * msg
, ...)
767 __attribute__ ((format (printf
, 3, 4)));
769 /// Set last error info struct.
770 void set_err(const smart_device::error_info
& err
)
773 /// Clear last error info.
777 /// Set last error number and default message.
778 /// Message is retrieved from get_msg_for_errno(no).
779 void set_err(int no
);
781 /// Set last error number and default message to any error_info.
782 /// Used by set_err(no).
783 void set_err_var(smart_device::error_info
* err
, int no
);
785 /// Convert error number into message, used by set_err(no).
786 /// Default implementation returns strerror(no).
787 virtual const char * get_msg_for_errno(int no
);
789 ///////////////////////////////////////////////////////////////////////////
792 /// Return device object for device 'name' with some 'type'.
793 /// 'type' is 0 if not specified by user.
794 /// Return 0 on error.
795 /// Default implementation selects between ata, scsi and custom device.
796 virtual smart_device
* get_smart_device(const char * name
, const char * type
);
798 /// Fill 'devlist' with devices of some 'type' with device names
799 /// specified by some optional 'pattern'.
800 /// Return false on error.
801 virtual bool scan_smart_devices(smart_device_list
& devlist
, const char * type
,
802 const char * pattern
= 0) = 0;
805 /// Return standard ATA device.
806 virtual ata_device
* get_ata_device(const char * name
, const char * type
) = 0;
808 /// Return standard SCSI device.
809 virtual scsi_device
* get_scsi_device(const char * name
, const char * type
) = 0;
811 /// Autodetect device if no device type specified.
812 virtual smart_device
* autodetect_smart_device(const char * name
) = 0;
814 /// Return device for platform specific 'type'.
815 /// Default implementation returns 0.
816 virtual smart_device
* get_custom_smart_device(const char * name
, const char * type
);
818 /// Return valid 'type' args accepted by above.
819 /// This is called in get_valid_dev_types_str().
820 /// Default implementation returns empty string.
821 virtual std::string
get_valid_custom_dev_types_str();
823 /// Return ATA->SCSI filter for SAT or USB.
824 /// Override only if platform needs special handling.
825 virtual ata_device
* get_sat_device(const char * type
, scsi_device
* scsidev
);
826 //{ implemented in scsiata.cpp }
829 /// Try to detect a SAT device behind a SCSI interface.
830 /// Inquiry data can be passed if available.
831 /// Return appropriate device if yes, otherwise 0.
832 /// Override only if platform needs special handling.
833 virtual ata_device
* autodetect_sat_device(scsi_device
* scsidev
,
834 const unsigned char * inqdata
, unsigned inqsize
);
835 //{ implemented in scsiata.cpp }
837 /// Get type name for USB device with known VENDOR:PRODUCT ID.
838 /// Return name if device known and supported, otherwise 0.
839 virtual const char * get_usb_dev_type_by_id(int vendor_id
, int product_id
,
841 //{ implemented in scsiata.cpp }
844 /// Set interface to use, must be called from init().
845 static void set(smart_interface
* intf
)
846 { s_instance
= intf
; }
850 smart_device::error_info m_err
;
852 friend smart_interface
* smi(); // below
853 static smart_interface
* s_instance
; ///< Pointer to the interface object.
855 // Prevent copy/assigment
856 smart_interface(const smart_interface
&);
857 void operator=(const smart_interface
&);
861 /////////////////////////////////////////////////////////////////////////////
864 /// Global access to the (usually singleton) smart_interface
865 inline smart_interface
* smi()
866 { return smart_interface::s_instance
; }
868 /////////////////////////////////////////////////////////////////////////////
870 #endif // DEV_INTERFACE_H