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