]> git.proxmox.com Git - mirror_smartmontools-debian.git/blame - dev_interface.h
Updated changelog
[mirror_smartmontools-debian.git] / dev_interface.h
CommitLineData
2127e193
GI
1/*
2 * dev_interface.h
3 *
4 * Home page of code is: http://smartmontools.sourceforge.net
5 *
cfbba5b9 6 * Copyright (C) 2008-11 Christian Franke <smartmontools-support@lists.sourceforge.net>
2127e193
GI
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
cfbba5b9 21#define DEV_INTERFACE_H_CVSID "$Id: dev_interface.h 3256 2011-02-08 22:13:41Z chrfranke $\n"
2127e193 22
bed94269 23#include <stdexcept>
2127e193
GI
24#include <string>
25#include <vector>
26
27#if !defined(__GNUC__) && !defined(__attribute__)
28#define __attribute__(x) /**/
29#endif
30
31#ifdef _MSC_VER // Disable MSVC warning
32#pragma warning(disable:4250) // 'class1' : inherits 'class2::member' via dominance
33#endif
34
35/////////////////////////////////////////////////////////////////////////////
36// Common functionality for all device types
37
38// Forward declarations
39class smart_interface;
40class ata_device;
41class scsi_device;
42
43/// Base class for all devices
44class smart_device
45{
46// Types
47public:
48 /// Device info strings
49 struct device_info {
50 device_info()
51 { }
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)
55 { }
56
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
61 };
62
63 /// Error (number,message) pair
64 struct error_info {
65 explicit error_info(int n = 0)
66 : no(n) { }
67 error_info(int n, const char * m)
68 : no(n), msg(m) { }
69 void clear()
70 { no = 0; msg.erase(); }
71
72 int no; ///< Error number
73 std::string msg; ///< Error message
74 };
75
76// Construction
77protected:
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);
82
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);
88
89public:
90 virtual ~smart_device() throw();
91
92// Attributes
93public:
94 ///////////////////////////////////////////////
95 // Dynamic downcasts to actual device flavor
96
97 /// Return true if ATA device
98 bool is_ata() const
99 { return !!m_ata_ptr; }
100 /// Return true if SCSI device
101 bool is_scsi() const
102 { return !!m_scsi_ptr; }
103
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; }
cfbba5b9 113 /// Downcast to SCSI device (const).
2127e193
GI
114 const scsi_device * to_scsi() const
115 { return m_scsi_ptr; }
116
117 ///////////////////////////////////////////////
118 // Device information
119
120 /// Get device info struct.
121 const device_info & get_info() const
122 { return m_info; }
123
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(); }
130 /// Get device type.
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(); }
136
137protected:
138 /// R/W access to device info struct.
139 device_info & set_info()
140 { return m_info; }
141
142public:
143 ///////////////////////////////////////////////
144 // Last error information
145
146 /// Get last error info struct.
147 const error_info & get_err() const
148 { return m_err; }
149 /// Get last error number.
150 int get_errno() const
151 { return m_err.no; }
152 /// Get last error message.
153 const char * get_errmsg() const
154 { return m_err.msg.c_str(); }
155
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)));
161
162 /// Set last error info struct.
163 bool set_err(const error_info & err)
164 { m_err = err; return false; }
165
166 /// Clear last error info.
167 void clear_err()
168 { m_err.clear(); }
169
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);
173
174// Operations
175public:
176 ///////////////////////////////////////////////
177 // Device open/close
178 // Must be implemented in derived class
179
180 /// Return true if device is open.
181 virtual bool is_open() const = 0;
182
183 /// Open device, return false on error.
184 virtual bool open() = 0;
185
186 /// Close device, return false on error.
187 virtual bool close() = 0;
188
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();
194
195 ///////////////////////////////////////////////
196 // Support for tunnelled devices
197
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;
201
202 /// Release ownership of other device.
203 /// Default implementation does nothing.
204 virtual void release(const smart_device * dev);
205
206protected:
207 /// Set dynamic downcast for ATA
208 void this_is_ata(ata_device * ata);
209 // {see below;}
210
211 /// Set dynamic downcast for SCSI
212 void this_is_scsi(scsi_device * scsi);
213 // {see below;}
214
215 /// Get interface which produced this object.
216 smart_interface * smi()
217 { return m_intf; }
218 /// Get interface which produced this object (const).
219 const smart_interface * smi() const
220 { return m_intf; }
221
222// Implementation
223private:
224 smart_interface * m_intf;
225 device_info m_info;
226 ata_device * m_ata_ptr;
227 scsi_device * m_scsi_ptr;
228 error_info m_err;
229
230 // Prevent copy/assigment
231 smart_device(const smart_device &);
232 void operator=(const smart_device &);
233};
234
235
236/////////////////////////////////////////////////////////////////////////////
237// ATA specific interface
238
cfbba5b9 239/// ATA register value and info whether it has ever been set
2127e193
GI
240// (Automatically set by first assignment)
241class ata_register
242{
243public:
244 ata_register()
245 : m_val(0x00), m_is_set(false) { }
246
cfbba5b9
GI
247 ata_register & operator=(unsigned char x)
248 { m_val = x; m_is_set = true; return * this; }
2127e193
GI
249
250 unsigned char val() const
251 { return m_val; }
252 operator unsigned char() const
253 { return m_val; }
254
255 bool is_set() const
256 { return m_is_set; }
257
258private:
259 unsigned char m_val; ///< Register value
260 bool m_is_set; ///< true if set
261};
262
263/// ATA Input registers (for 28-bit commands)
264struct ata_in_regs
265{
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
274
275 /// Return true if any register is set
276 bool is_set() const
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()); }
280};
281
282/// ATA Output registers (for 28-bit commands)
283struct ata_out_regs
284{
285 ata_register error;
286 ata_register sector_count;
287 ata_register lba_low;
288 ata_register lba_mid;
289 ata_register lba_high;
290 ata_register device;
291 ata_register status;
292
293 /// Return true if any register is set
294 bool is_set() const
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()); }
298};
299
300
301/// 16-bit alias to a 8-bit ATA register pair.
302class ata_reg_alias_16
303{
304public:
305 ata_reg_alias_16(ata_register & lo, ata_register & hi)
306 : m_lo(lo), m_hi(hi) { }
307
cfbba5b9
GI
308 ata_reg_alias_16 & operator=(unsigned short x)
309 { m_lo = (unsigned char) x;
310 m_hi = (unsigned char)(x >> 8);
2127e193
GI
311 return * this; }
312
313 unsigned short val() const
314 { return m_lo | (m_hi << 8); }
315 operator unsigned short() const
316 { return m_lo | (m_hi << 8); }
317
318private:
319 ata_register & m_lo, & m_hi;
320
321 // References must not be copied.
322 ata_reg_alias_16(const ata_reg_alias_16 &);
323 void operator=(const ata_reg_alias_16 &);
324};
325
326
a23d5117
GI
327/// 48-bit alias to six 8-bit ATA registers (for LBA).
328class ata_reg_alias_48
329{
330public:
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)
335 { }
336
cfbba5b9 337 ata_reg_alias_48 & operator=(uint64_t x)
a23d5117 338 {
cfbba5b9
GI
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);
a23d5117
GI
345 return * this;
346 }
347
348 uint64_t val() const
349 {
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));
356 }
357
358 operator uint64_t() const
359 { return val(); }
360
361private:
362 ata_register & m_ll, & m_lm, & m_lh,
363 & m_hl, & m_hm, & m_hh;
364
365 // References must not be copied.
366 ata_reg_alias_48(const ata_reg_alias_48 &);
367 void operator=(const ata_reg_alias_48 &);
368};
369
370
2127e193
GI
371/// ATA Input registers for 48-bit commands
372// See section 4.14 of T13/1532D Volume 1 Revision 4b
373//
374// Uses ATA-6/7 method to specify 16-bit registers as
375// recent (low byte) and previous (high byte) content of
376// 8-bit registers.
377//
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.)
381//
382struct ata_in_regs_48bit
383: public ata_in_regs // "most recently written" registers
384{
385 ata_in_regs prev; ///< "previous content"
386
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;
393
a23d5117
GI
394 // 48-bit alias to all 8-bit LBA registers.
395 ata_reg_alias_48 lba_48;
396
2127e193
GI
397 /// Return true if 48-bit command
398 bool is_48bit_cmd() const
399 { return prev.is_set(); }
400
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); }
405
406 ata_in_regs_48bit();
407};
408
409
410/// ATA Output registers for 48-bit commands
411struct ata_out_regs_48bit
412: public ata_out_regs // read with HOB=0
413{
414 ata_out_regs prev; ///< read with HOB=1
415
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;
421
a23d5117
GI
422 // 48-bit alias to all 8-bit LBA registers.
423 ata_reg_alias_48 lba_48;
424
2127e193
GI
425 ata_out_regs_48bit();
426};
427
428
429/// Flags for each ATA output register
430struct ata_out_regs_flags
431{
432 bool error, sector_count, lba_low, lba_mid, lba_high, device, status;
433
434 /// Return true if any flag is set.
435 bool is_set() const
436 { return ( error || sector_count || lba_low
437 || lba_mid || lba_high || device || status); }
438
439 /// Default constructor clears all flags.
440 ata_out_regs_flags()
441 : error(false), sector_count(false), lba_low(false), lba_mid(false),
442 lba_high(false), device(false), status(false) { }
443};
444
445
446/// ATA pass through input parameters
447struct ata_cmd_in
448{
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
454
455 /// Prepare for 28-bit DATA IN command
456 void set_data_in(void * buf, unsigned nsectors)
457 {
458 buffer = buf;
459 in_regs.sector_count = nsectors;
460 direction = data_in;
461 size = nsectors * 512;
462 }
463
464 /// Prepare for 28-bit DATA OUT command
465 void set_data_out(const void * buf, unsigned nsectors)
466 {
467 buffer = const_cast<void *>(buf);
468 in_regs.sector_count = nsectors;
469 direction = data_out;
470 size = nsectors * 512;
471 }
472
473 /// Prepare for 48-bit DATA IN command
474 void set_data_in_48bit(void * buf, unsigned nsectors)
475 {
476 buffer = buf;
477 // Note: This also sets 'in_regs.is_48bit_cmd()'
478 in_regs.sector_count_16 = nsectors;
479 direction = data_in;
480 size = nsectors * 512;
481 }
482
483 ata_cmd_in();
484};
485
486/// ATA pass through output parameters
487struct ata_cmd_out
488{
489 ata_out_regs_48bit out_regs; ///< Output registers
490
491 ata_cmd_out();
492};
493
494/// ATA device access
495class ata_device
496: virtual public /*extends*/ smart_device
497{
498public:
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;
503
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);
508
509 /// Return true if OS caches ATA identify sector.
510 /// Default implementation returns false.
511 virtual bool ata_identify_is_cached() const;
512
513protected:
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);
520
521 /// Default constructor, registers device as ATA.
522 ata_device()
523 : smart_device(never_called)
524 { this_is_ata(this); }
525};
526
527
528/////////////////////////////////////////////////////////////////////////////
529// SCSI specific interface
530
531struct scsi_cmnd_io;
532
533/// SCSI device access
534class scsi_device
535: virtual public /*extends*/ smart_device
536{
537public:
538 /// SCSI pass through.
539 /// Returns false on error.
540 virtual bool scsi_pass_through(scsi_cmnd_io * iop) = 0;
541
542protected:
543 /// Default constructor, registers device as SCSI.
544 scsi_device()
545 : smart_device(never_called)
546 { this_is_scsi(this); }
547};
548
549
550/////////////////////////////////////////////////////////////////////////////
551
552// Set dynamic downcasts
553// Note that due to virtual inheritance,
554// (ata == this) does not imply ((void*)ata == (void*)this))
555
556inline void smart_device::this_is_ata(ata_device * ata)
557{
558 m_ata_ptr = (ata == this ? ata : 0);
559}
560
561inline void smart_device::this_is_scsi(scsi_device * scsi)
562{
563 m_scsi_ptr = (scsi == this ? scsi : 0);
564}
565
566
bed94269
GI
567/////////////////////////////////////////////////////////////////////////////
568/// Smart pointer class for device pointers
569
570template <class Dev>
571class any_device_auto_ptr
572{
573public:
574 typedef Dev device_type;
575
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) { }
581
582 /// Destructor deletes device object.
583 ~any_device_auto_ptr() throw()
584 { reset(); }
585
586 /// Assign a new pointer.
587 /// Throws if a pointer is already assigned.
588 void operator=(device_type * dev)
589 {
590 if (m_dev)
591 fail();
592 m_dev = dev;
593 }
594
595 /// Delete device object and clear the pointer.
596 void reset()
597 {
598 if (m_dev) {
599 if (m_base_dev && m_dev->owns(m_base_dev))
600 m_dev->release(m_base_dev);
601 delete m_dev;
cfbba5b9 602 m_dev = 0;
bed94269 603 }
bed94269
GI
604 }
605
606 /// Return the pointer and release ownership.
607 device_type * release()
608 {
609 device_type * dev = m_dev;
610 m_dev = 0;
611 return dev;
612 }
613
614 /// Replace the pointer.
615 /// Used to call dev->autodetect_open().
616 void replace(device_type * dev)
617 { m_dev = dev; }
618
619 /// Return the pointer.
620 device_type * get() const
621 { return m_dev; }
622
623 /// Pointer dereferencing.
624 device_type & operator*() const
625 { return *m_dev; }
626
627 /// Pointer dereferencing.
628 device_type * operator->() const
629 { return m_dev; }
630
631 /// For (ptr != 0) check.
632 operator bool() const
633 { return !!m_dev; }
634
635 /// For (ptr == 0) check.
636 bool operator !() const
637 { return !m_dev; }
638
639private:
640 device_type * m_dev;
641 smart_device * m_base_dev;
642
643 void fail() const
644 { throw std::logic_error("any_device_auto_ptr: wrong usage"); }
645
646 // Prevent copy/assignment
647 any_device_auto_ptr(const any_device_auto_ptr<Dev> &);
648 void operator=(const any_device_auto_ptr<Dev> &);
649};
650
651typedef any_device_auto_ptr<smart_device> smart_device_auto_ptr;
652typedef any_device_auto_ptr<ata_device> ata_device_auto_ptr;
653typedef any_device_auto_ptr<scsi_device> scsi_device_auto_ptr;
654
655
2127e193
GI
656/////////////////////////////////////////////////////////////////////////////
657// smart_device_list
658
659/// List of devices for DEVICESCAN
660class smart_device_list
661{
662// Construction
663public:
664 smart_device_list()
665 { }
666
667 ~smart_device_list() throw()
668 {
669 for (unsigned i = 0; i < m_list.size(); i++)
670 delete m_list[i];
671 }
672
673// Attributes
674 unsigned size() const
675 { return m_list.size(); }
676
677// Operations
678 void clear()
679 {
680 for (unsigned i = 0; i < m_list.size(); i++)
681 delete m_list[i];
682 m_list.clear();
683 }
684
685
2127e193
GI
686 void push_back(smart_device * dev)
687 { m_list.push_back(dev); }
688
bed94269
GI
689 void push_back(smart_device_auto_ptr & dev)
690 {
691 m_list.push_back(dev.get());
692 dev.release();
693 }
694
2127e193
GI
695 smart_device * at(unsigned i)
696 { return m_list.at(i); }
697
698 const smart_device * at(unsigned i) const
699 { return m_list.at(i); }
700
701 smart_device * release(unsigned i)
702 {
703 smart_device * dev = m_list.at(i);
704 m_list[i] = 0;
705 return dev;
706 }
707
708// Implementation
709private:
710 std::vector<smart_device *> m_list;
711
712 // Prevent copy/assigment
713 smart_device_list(const smart_device_list &);
714 void operator=(const smart_device_list &);
715};
716
717
718/////////////////////////////////////////////////////////////////////////////
719// smart_interface
720
721/// The platform interface abstraction
722class smart_interface
723{
724public:
725 /// Initialize platform interface and register with smi().
726 /// Must be implemented by platform module and register interface with set()
727 static void init();
728
729 smart_interface()
730 { }
731
732 virtual ~smart_interface() throw()
733 { }
734
54965743
GI
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();
2127e193
GI
738
739 /// Return valid args for device type option/directive.
54965743
GI
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();
2127e193
GI
743
744 /// Return example string for program 'appname'.
54965743 745 /// Default implementation returns empty string.
2127e193
GI
746 /// For the migration of print_smartctl_examples(),
747 /// function is allowed to print examples to stdout.
748 /// TODO: Remove this hack.
54965743 749 virtual std::string get_app_examples(const char * appname);
2127e193
GI
750
751 ///////////////////////////////////////////////
752 // Last error information
753
754 /// Get last error info struct.
755 const smart_device::error_info & get_err() const
756 { return m_err; }
757 /// Get last error number.
758 int get_errno() const
759 { return m_err.no; }
760 /// Get last error message.
761 const char * get_errmsg() const
762 { return m_err.msg.c_str(); }
763
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)));
768
769 /// Set last error info struct.
770 void set_err(const smart_device::error_info & err)
771 { m_err = err; }
772
773 /// Clear last error info.
774 void clear_err()
775 { m_err.clear(); }
776
777 /// Set last error number and default message.
778 /// Message is retrieved from get_msg_for_errno(no).
779 void set_err(int no);
780
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);
784
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);
788
789 ///////////////////////////////////////////////////////////////////////////
790 // Device factory:
791
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);
797
cfbba5b9 798 /// Fill 'devlist' with devices of some 'type' with device names
2127e193
GI
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;
803
804protected:
805 /// Return standard ATA device.
806 virtual ata_device * get_ata_device(const char * name, const char * type) = 0;
807
808 /// Return standard SCSI device.
809 virtual scsi_device * get_scsi_device(const char * name, const char * type) = 0;
810
811 /// Autodetect device if no device type specified.
812 virtual smart_device * autodetect_smart_device(const char * name) = 0;
813
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);
817
818 /// Return valid 'type' args accepted by above.
819 /// This is called in get_valid_dev_types_str().
54965743
GI
820 /// Default implementation returns empty string.
821 virtual std::string get_valid_custom_dev_types_str();
2127e193
GI
822
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 }
827
828public:
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 }
836
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,
840 int version = -1);
841 //{ implemented in scsiata.cpp }
842
843protected:
844 /// Set interface to use, must be called from init().
845 static void set(smart_interface * intf)
846 { s_instance = intf; }
847
848// Implementation
849private:
850 smart_device::error_info m_err;
851
852 friend smart_interface * smi(); // below
853 static smart_interface * s_instance; ///< Pointer to the interface object.
854
855 // Prevent copy/assigment
856 smart_interface(const smart_interface &);
857 void operator=(const smart_interface &);
858};
859
860
861/////////////////////////////////////////////////////////////////////////////
862// smi()
863
864/// Global access to the (usually singleton) smart_interface
865inline smart_interface * smi()
866 { return smart_interface::s_instance; }
867
868/////////////////////////////////////////////////////////////////////////////
869
870#endif // DEV_INTERFACE_H