]> git.proxmox.com Git - mirror_smartmontools-debian.git/blame - dev_interface.h
Enhance dh_clean to clean up better
[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
ee38a438 21#define DEV_INTERFACE_H_CVSID "$Id: dev_interface.h 3663 2012-10-24 20:35:55Z 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
f4e463df
GI
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;
153
2127e193
GI
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, ...)
d008864d 158 __attribute_format_printf(3, 4);
2127e193
GI
159
160 /// Set last error info struct.
161 bool set_err(const error_info & err)
162 { m_err = err; return false; }
163
164 /// Clear last error info.
165 void clear_err()
166 { m_err.clear(); }
167
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);
171
172// Operations
173public:
174 ///////////////////////////////////////////////
175 // Device open/close
176 // Must be implemented in derived class
177
178 /// Return true if device is open.
179 virtual bool is_open() const = 0;
180
181 /// Open device, return false on error.
182 virtual bool open() = 0;
183
184 /// Close device, return false on error.
185 virtual bool close() = 0;
186
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.
f4e463df 190 /// Default implementation calls 'open()' and returns 'this'.
2127e193
GI
191 virtual smart_device * autodetect_open();
192
193 ///////////////////////////////////////////////
194 // Support for tunnelled devices
195
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;
199
200 /// Release ownership of other device.
201 /// Default implementation does nothing.
202 virtual void release(const smart_device * dev);
203
204protected:
2127e193
GI
205 /// Get interface which produced this object.
206 smart_interface * smi()
207 { return m_intf; }
208 /// Get interface which produced this object (const).
209 const smart_interface * smi() const
210 { return m_intf; }
211
212// Implementation
213private:
214 smart_interface * m_intf;
215 device_info m_info;
d008864d
GI
216 error_info m_err;
217
218 // Pointers for to_ata(), to_scsi(),
219 // set by ATA/SCSI interface classes.
220 friend class ata_device;
2127e193 221 ata_device * m_ata_ptr;
d008864d 222 friend class scsi_device;
2127e193 223 scsi_device * m_scsi_ptr;
2127e193
GI
224
225 // Prevent copy/assigment
226 smart_device(const smart_device &);
227 void operator=(const smart_device &);
228};
229
230
231/////////////////////////////////////////////////////////////////////////////
232// ATA specific interface
233
cfbba5b9 234/// ATA register value and info whether it has ever been set
2127e193
GI
235// (Automatically set by first assignment)
236class ata_register
237{
238public:
239 ata_register()
240 : m_val(0x00), m_is_set(false) { }
241
cfbba5b9
GI
242 ata_register & operator=(unsigned char x)
243 { m_val = x; m_is_set = true; return * this; }
2127e193
GI
244
245 unsigned char val() const
246 { return m_val; }
247 operator unsigned char() const
248 { return m_val; }
249
250 bool is_set() const
251 { return m_is_set; }
252
253private:
254 unsigned char m_val; ///< Register value
255 bool m_is_set; ///< true if set
256};
257
258/// ATA Input registers (for 28-bit commands)
259struct ata_in_regs
260{
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
269
270 /// Return true if any register is set
271 bool is_set() const
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()); }
275};
276
277/// ATA Output registers (for 28-bit commands)
278struct ata_out_regs
279{
280 ata_register error;
281 ata_register sector_count;
282 ata_register lba_low;
283 ata_register lba_mid;
284 ata_register lba_high;
285 ata_register device;
286 ata_register status;
287
288 /// Return true if any register is set
289 bool is_set() const
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()); }
293};
294
295
296/// 16-bit alias to a 8-bit ATA register pair.
297class ata_reg_alias_16
298{
299public:
300 ata_reg_alias_16(ata_register & lo, ata_register & hi)
301 : m_lo(lo), m_hi(hi) { }
302
cfbba5b9
GI
303 ata_reg_alias_16 & operator=(unsigned short x)
304 { m_lo = (unsigned char) x;
305 m_hi = (unsigned char)(x >> 8);
2127e193
GI
306 return * this; }
307
308 unsigned short val() const
309 { return m_lo | (m_hi << 8); }
310 operator unsigned short() const
311 { return m_lo | (m_hi << 8); }
312
313private:
314 ata_register & m_lo, & m_hi;
315
316 // References must not be copied.
317 ata_reg_alias_16(const ata_reg_alias_16 &);
318 void operator=(const ata_reg_alias_16 &);
319};
320
321
a23d5117
GI
322/// 48-bit alias to six 8-bit ATA registers (for LBA).
323class ata_reg_alias_48
324{
325public:
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)
330 { }
331
cfbba5b9 332 ata_reg_alias_48 & operator=(uint64_t x)
a23d5117 333 {
cfbba5b9
GI
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);
a23d5117
GI
340 return * this;
341 }
342
343 uint64_t val() const
344 {
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));
351 }
352
353 operator uint64_t() const
354 { return val(); }
355
356private:
357 ata_register & m_ll, & m_lm, & m_lh,
358 & m_hl, & m_hm, & m_hh;
359
360 // References must not be copied.
361 ata_reg_alias_48(const ata_reg_alias_48 &);
362 void operator=(const ata_reg_alias_48 &);
363};
364
365
2127e193
GI
366/// ATA Input registers for 48-bit commands
367// See section 4.14 of T13/1532D Volume 1 Revision 4b
368//
369// Uses ATA-6/7 method to specify 16-bit registers as
370// recent (low byte) and previous (high byte) content of
371// 8-bit registers.
372//
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.)
376//
377struct ata_in_regs_48bit
378: public ata_in_regs // "most recently written" registers
379{
380 ata_in_regs prev; ///< "previous content"
381
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;
388
a23d5117
GI
389 // 48-bit alias to all 8-bit LBA registers.
390 ata_reg_alias_48 lba_48;
391
2127e193
GI
392 /// Return true if 48-bit command
393 bool is_48bit_cmd() const
394 { return prev.is_set(); }
395
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); }
400
401 ata_in_regs_48bit();
402};
403
404
405/// ATA Output registers for 48-bit commands
406struct ata_out_regs_48bit
407: public ata_out_regs // read with HOB=0
408{
409 ata_out_regs prev; ///< read with HOB=1
410
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;
416
a23d5117
GI
417 // 48-bit alias to all 8-bit LBA registers.
418 ata_reg_alias_48 lba_48;
419
2127e193
GI
420 ata_out_regs_48bit();
421};
422
423
424/// Flags for each ATA output register
425struct ata_out_regs_flags
426{
427 bool error, sector_count, lba_low, lba_mid, lba_high, device, status;
428
429 /// Return true if any flag is set.
430 bool is_set() const
431 { return ( error || sector_count || lba_low
432 || lba_mid || lba_high || device || status); }
433
434 /// Default constructor clears all flags.
435 ata_out_regs_flags()
436 : error(false), sector_count(false), lba_low(false), lba_mid(false),
437 lba_high(false), device(false), status(false) { }
438};
439
440
441/// ATA pass through input parameters
442struct ata_cmd_in
443{
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
449
450 /// Prepare for 28-bit DATA IN command
451 void set_data_in(void * buf, unsigned nsectors)
452 {
453 buffer = buf;
454 in_regs.sector_count = nsectors;
455 direction = data_in;
456 size = nsectors * 512;
457 }
458
459 /// Prepare for 28-bit DATA OUT command
460 void set_data_out(const void * buf, unsigned nsectors)
461 {
462 buffer = const_cast<void *>(buf);
463 in_regs.sector_count = nsectors;
464 direction = data_out;
465 size = nsectors * 512;
466 }
467
468 /// Prepare for 48-bit DATA IN command
469 void set_data_in_48bit(void * buf, unsigned nsectors)
470 {
471 buffer = buf;
472 // Note: This also sets 'in_regs.is_48bit_cmd()'
473 in_regs.sector_count_16 = nsectors;
474 direction = data_in;
475 size = nsectors * 512;
476 }
477
478 ata_cmd_in();
479};
480
481/// ATA pass through output parameters
482struct ata_cmd_out
483{
484 ata_out_regs_48bit out_regs; ///< Output registers
485
486 ata_cmd_out();
487};
488
489/// ATA device access
490class ata_device
491: virtual public /*extends*/ smart_device
492{
493public:
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;
498
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);
503
504 /// Return true if OS caches ATA identify sector.
505 /// Default implementation returns false.
506 virtual bool ata_identify_is_cached() const;
507
508protected:
ee38a438
GI
509 /// Flags for ata_cmd_is_supported().
510 enum {
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
517 };
518
2127e193 519 /// Check command input parameters.
ee38a438 520 /// Return false if required features are not implemented.
2127e193 521 /// Calls set_err(...) accordingly.
ee38a438
GI
522 bool ata_cmd_is_supported(const ata_cmd_in & in, unsigned flags,
523 const char * type = 0);
524
525 /// Check command input parameters (old version).
526 // TODO: Remove if no longer used.
2127e193
GI
527 bool ata_cmd_is_ok(const ata_cmd_in & in,
528 bool data_out_support = false,
529 bool multi_sector_support = false,
ee38a438
GI
530 bool ata_48bit_support = false)
531 {
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));
537 }
2127e193 538
d008864d
GI
539 /// Hide/unhide ATA interface.
540 void hide_ata(bool hide = true)
541 { m_ata_ptr = (!hide ? this : 0); }
542
2127e193
GI
543 /// Default constructor, registers device as ATA.
544 ata_device()
545 : smart_device(never_called)
d008864d 546 { hide_ata(false); }
2127e193
GI
547};
548
549
550/////////////////////////////////////////////////////////////////////////////
551// SCSI specific interface
552
553struct scsi_cmnd_io;
554
555/// SCSI device access
556class scsi_device
557: virtual public /*extends*/ smart_device
558{
559public:
560 /// SCSI pass through.
561 /// Returns false on error.
562 virtual bool scsi_pass_through(scsi_cmnd_io * iop) = 0;
563
564protected:
d008864d
GI
565 /// Hide/unhide SCSI interface.
566 void hide_scsi(bool hide = true)
567 { m_scsi_ptr = (!hide ? this : 0); }
568
2127e193
GI
569 /// Default constructor, registers device as SCSI.
570 scsi_device()
571 : smart_device(never_called)
d008864d 572 { hide_scsi(false); }
2127e193
GI
573};
574
575
bed94269
GI
576/////////////////////////////////////////////////////////////////////////////
577/// Smart pointer class for device pointers
578
579template <class Dev>
580class any_device_auto_ptr
581{
582public:
583 typedef Dev device_type;
584
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) { }
590
591 /// Destructor deletes device object.
592 ~any_device_auto_ptr() throw()
593 { reset(); }
594
595 /// Assign a new pointer.
596 /// Throws if a pointer is already assigned.
597 void operator=(device_type * dev)
598 {
599 if (m_dev)
600 fail();
601 m_dev = dev;
602 }
603
604 /// Delete device object and clear the pointer.
605 void reset()
606 {
607 if (m_dev) {
608 if (m_base_dev && m_dev->owns(m_base_dev))
609 m_dev->release(m_base_dev);
610 delete m_dev;
cfbba5b9 611 m_dev = 0;
bed94269 612 }
bed94269
GI
613 }
614
615 /// Return the pointer and release ownership.
616 device_type * release()
617 {
618 device_type * dev = m_dev;
619 m_dev = 0;
620 return dev;
621 }
622
623 /// Replace the pointer.
624 /// Used to call dev->autodetect_open().
625 void replace(device_type * dev)
626 { m_dev = dev; }
627
628 /// Return the pointer.
629 device_type * get() const
630 { return m_dev; }
631
632 /// Pointer dereferencing.
633 device_type & operator*() const
634 { return *m_dev; }
635
636 /// Pointer dereferencing.
637 device_type * operator->() const
638 { return m_dev; }
639
640 /// For (ptr != 0) check.
641 operator bool() const
642 { return !!m_dev; }
643
644 /// For (ptr == 0) check.
645 bool operator !() const
646 { return !m_dev; }
647
648private:
649 device_type * m_dev;
650 smart_device * m_base_dev;
651
652 void fail() const
653 { throw std::logic_error("any_device_auto_ptr: wrong usage"); }
654
655 // Prevent copy/assignment
656 any_device_auto_ptr(const any_device_auto_ptr<Dev> &);
657 void operator=(const any_device_auto_ptr<Dev> &);
658};
659
660typedef any_device_auto_ptr<smart_device> smart_device_auto_ptr;
661typedef any_device_auto_ptr<ata_device> ata_device_auto_ptr;
662typedef any_device_auto_ptr<scsi_device> scsi_device_auto_ptr;
663
664
2127e193
GI
665/////////////////////////////////////////////////////////////////////////////
666// smart_device_list
667
668/// List of devices for DEVICESCAN
669class smart_device_list
670{
671// Construction
672public:
673 smart_device_list()
674 { }
675
676 ~smart_device_list() throw()
677 {
678 for (unsigned i = 0; i < m_list.size(); i++)
679 delete m_list[i];
680 }
681
682// Attributes
683 unsigned size() const
684 { return m_list.size(); }
685
686// Operations
687 void clear()
688 {
689 for (unsigned i = 0; i < m_list.size(); i++)
690 delete m_list[i];
691 m_list.clear();
692 }
693
694
2127e193
GI
695 void push_back(smart_device * dev)
696 { m_list.push_back(dev); }
697
bed94269
GI
698 void push_back(smart_device_auto_ptr & dev)
699 {
700 m_list.push_back(dev.get());
701 dev.release();
702 }
703
2127e193
GI
704 smart_device * at(unsigned i)
705 { return m_list.at(i); }
706
707 const smart_device * at(unsigned i) const
708 { return m_list.at(i); }
709
710 smart_device * release(unsigned i)
711 {
712 smart_device * dev = m_list.at(i);
713 m_list[i] = 0;
714 return dev;
715 }
716
717// Implementation
718private:
719 std::vector<smart_device *> m_list;
720
721 // Prevent copy/assigment
722 smart_device_list(const smart_device_list &);
723 void operator=(const smart_device_list &);
724};
725
726
727/////////////////////////////////////////////////////////////////////////////
728// smart_interface
729
730/// The platform interface abstraction
731class smart_interface
732{
733public:
734 /// Initialize platform interface and register with smi().
735 /// Must be implemented by platform module and register interface with set()
736 static void init();
737
738 smart_interface()
739 { }
740
741 virtual ~smart_interface() throw()
742 { }
743
54965743
GI
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();
2127e193
GI
747
748 /// Return valid args for device type option/directive.
54965743
GI
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();
2127e193
GI
752
753 /// Return example string for program 'appname'.
54965743 754 /// Default implementation returns empty string.
2127e193
GI
755 /// For the migration of print_smartctl_examples(),
756 /// function is allowed to print examples to stdout.
757 /// TODO: Remove this hack.
54965743 758 virtual std::string get_app_examples(const char * appname);
2127e193 759
e165493d
GI
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();
765
d008864d
GI
766 /// Disable/Enable system auto standby/sleep mode.
767 /// Return false if unsupported or if system is running
768 /// on battery.
769 /// Default implementation returns false.
770 virtual bool disable_system_auto_standby(bool disable);
771
772
2127e193
GI
773 ///////////////////////////////////////////////
774 // Last error information
775
776 /// Get last error info struct.
777 const smart_device::error_info & get_err() const
778 { return m_err; }
779 /// Get last error number.
780 int get_errno() const
781 { return m_err.no; }
782 /// Get last error message.
783 const char * get_errmsg() const
784 { return m_err.msg.c_str(); }
785
786 /// Set last error number and message.
787 /// Printf()-like formatting is supported.
d008864d
GI
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);
2127e193
GI
791
792 /// Set last error info struct.
d008864d
GI
793 bool set_err(const smart_device::error_info & err)
794 { m_err = err; return false; }
2127e193
GI
795
796 /// Clear last error info.
797 void clear_err()
798 { m_err.clear(); }
799
800 /// Set last error number and default message.
801 /// Message is retrieved from get_msg_for_errno(no).
d008864d 802 bool set_err(int no);
2127e193
GI
803
804 /// Set last error number and default message to any error_info.
805 /// Used by set_err(no).
d008864d 806 bool set_err_var(smart_device::error_info * err, int no);
2127e193
GI
807
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);
811
812 ///////////////////////////////////////////////////////////////////////////
813 // Device factory:
814
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);
820
cfbba5b9 821 /// Fill 'devlist' with devices of some 'type' with device names
2127e193
GI
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;
826
827protected:
828 /// Return standard ATA device.
829 virtual ata_device * get_ata_device(const char * name, const char * type) = 0;
830
831 /// Return standard SCSI device.
832 virtual scsi_device * get_scsi_device(const char * name, const char * type) = 0;
833
834 /// Autodetect device if no device type specified.
835 virtual smart_device * autodetect_smart_device(const char * name) = 0;
836
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);
840
841 /// Return valid 'type' args accepted by above.
842 /// This is called in get_valid_dev_types_str().
54965743
GI
843 /// Default implementation returns empty string.
844 virtual std::string get_valid_custom_dev_types_str();
2127e193
GI
845
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 }
850
851public:
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 }
859
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,
863 int version = -1);
864 //{ implemented in scsiata.cpp }
865
866protected:
867 /// Set interface to use, must be called from init().
868 static void set(smart_interface * intf)
869 { s_instance = intf; }
870
871// Implementation
872private:
873 smart_device::error_info m_err;
874
875 friend smart_interface * smi(); // below
876 static smart_interface * s_instance; ///< Pointer to the interface object.
877
878 // Prevent copy/assigment
879 smart_interface(const smart_interface &);
880 void operator=(const smart_interface &);
881};
882
883
884/////////////////////////////////////////////////////////////////////////////
885// smi()
886
887/// Global access to the (usually singleton) smart_interface
888inline smart_interface * smi()
889 { return smart_interface::s_instance; }
890
891/////////////////////////////////////////////////////////////////////////////
892
893#endif // DEV_INTERFACE_H