Annotation of embedaddon/smartmontools/dev_interface.h, revision 1.1.1.2
1.1 misho 1: /*
2: * dev_interface.h
3: *
4: * Home page of code is: http://smartmontools.sourceforge.net
5: *
1.1.1.2 ! misho 6: * Copyright (C) 2008-12 Christian Franke <smartmontools-support@lists.sourceforge.net>
1.1 misho 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:
1.1.1.2 ! misho 21: #define DEV_INTERFACE_H_CVSID "$Id: dev_interface.h 3554 2012-06-01 20:11:46Z chrfranke $\n"
! 22:
! 23: #include "utility.h"
1.1 misho 24:
25: #include <stdexcept>
26: #include <string>
27: #include <vector>
28:
29: /////////////////////////////////////////////////////////////////////////////
30: // Common functionality for all device types
31:
32: // Forward declarations
33: class smart_interface;
34: class ata_device;
35: class scsi_device;
36:
37: /// Base class for all devices
38: class smart_device
39: {
40: // Types
41: public:
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
71: protected:
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:
83: public:
84: virtual ~smart_device() throw();
85:
86: // Attributes
87: public:
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; }
107: /// Downcast to SCSI device (const).
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:
131: protected:
132: /// R/W access to device info struct.
133: device_info & set_info()
134: { return m_info; }
135:
136: public:
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:
1.1.1.2 ! misho 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:
1.1 misho 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, ...)
1.1.1.2 ! misho 158: __attribute_format_printf(3, 4);
1.1 misho 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
173: public:
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.
1.1.1.2 ! misho 190: /// Default implementation calls 'open()' and returns 'this'.
1.1 misho 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:
204: protected:
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
213: private:
214: smart_interface * m_intf;
215: device_info m_info;
1.1.1.2 ! misho 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;
1.1 misho 221: ata_device * m_ata_ptr;
1.1.1.2 ! misho 222: friend class scsi_device;
1.1 misho 223: scsi_device * m_scsi_ptr;
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:
234: /// ATA register value and info whether it has ever been set
235: // (Automatically set by first assignment)
236: class ata_register
237: {
238: public:
239: ata_register()
240: : m_val(0x00), m_is_set(false) { }
241:
242: ata_register & operator=(unsigned char x)
243: { m_val = x; m_is_set = true; return * this; }
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:
253: private:
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)
259: struct 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)
278: struct 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.
297: class ata_reg_alias_16
298: {
299: public:
300: ata_reg_alias_16(ata_register & lo, ata_register & hi)
301: : m_lo(lo), m_hi(hi) { }
302:
303: ata_reg_alias_16 & operator=(unsigned short x)
304: { m_lo = (unsigned char) x;
305: m_hi = (unsigned char)(x >> 8);
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:
313: private:
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:
322: /// 48-bit alias to six 8-bit ATA registers (for LBA).
323: class ata_reg_alias_48
324: {
325: public:
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:
332: ata_reg_alias_48 & operator=(uint64_t x)
333: {
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);
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:
356: private:
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:
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: //
377: struct 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:
389: // 48-bit alias to all 8-bit LBA registers.
390: ata_reg_alias_48 lba_48;
391:
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
406: struct 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:
417: // 48-bit alias to all 8-bit LBA registers.
418: ata_reg_alias_48 lba_48;
419:
420: ata_out_regs_48bit();
421: };
422:
423:
424: /// Flags for each ATA output register
425: struct 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
442: struct 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
482: struct ata_cmd_out
483: {
484: ata_out_regs_48bit out_regs; ///< Output registers
485:
486: ata_cmd_out();
487: };
488:
489: /// ATA device access
490: class ata_device
491: : virtual public /*extends*/ smart_device
492: {
493: public:
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:
508: protected:
509: /// Check command input parameters.
510: /// Calls set_err(...) accordingly.
511: bool ata_cmd_is_ok(const ata_cmd_in & in,
512: bool data_out_support = false,
513: bool multi_sector_support = false,
514: bool ata_48bit_support = false);
515:
1.1.1.2 ! misho 516: /// Hide/unhide ATA interface.
! 517: void hide_ata(bool hide = true)
! 518: { m_ata_ptr = (!hide ? this : 0); }
! 519:
1.1 misho 520: /// Default constructor, registers device as ATA.
521: ata_device()
522: : smart_device(never_called)
1.1.1.2 ! misho 523: { hide_ata(false); }
1.1 misho 524: };
525:
526:
527: /////////////////////////////////////////////////////////////////////////////
528: // SCSI specific interface
529:
530: struct scsi_cmnd_io;
531:
532: /// SCSI device access
533: class scsi_device
534: : virtual public /*extends*/ smart_device
535: {
536: public:
537: /// SCSI pass through.
538: /// Returns false on error.
539: virtual bool scsi_pass_through(scsi_cmnd_io * iop) = 0;
540:
541: protected:
1.1.1.2 ! misho 542: /// Hide/unhide SCSI interface.
! 543: void hide_scsi(bool hide = true)
! 544: { m_scsi_ptr = (!hide ? this : 0); }
! 545:
1.1 misho 546: /// Default constructor, registers device as SCSI.
547: scsi_device()
548: : smart_device(never_called)
1.1.1.2 ! misho 549: { hide_scsi(false); }
1.1 misho 550: };
551:
552:
553: /////////////////////////////////////////////////////////////////////////////
554: /// Smart pointer class for device pointers
555:
556: template <class Dev>
557: class any_device_auto_ptr
558: {
559: public:
560: typedef Dev device_type;
561:
562: /// Construct from optional pointer to device
563: /// and optional pointer to base device.
564: explicit any_device_auto_ptr(device_type * dev = 0,
565: smart_device * base_dev = 0)
566: : m_dev(dev), m_base_dev(base_dev) { }
567:
568: /// Destructor deletes device object.
569: ~any_device_auto_ptr() throw()
570: { reset(); }
571:
572: /// Assign a new pointer.
573: /// Throws if a pointer is already assigned.
574: void operator=(device_type * dev)
575: {
576: if (m_dev)
577: fail();
578: m_dev = dev;
579: }
580:
581: /// Delete device object and clear the pointer.
582: void reset()
583: {
584: if (m_dev) {
585: if (m_base_dev && m_dev->owns(m_base_dev))
586: m_dev->release(m_base_dev);
587: delete m_dev;
588: m_dev = 0;
589: }
590: }
591:
592: /// Return the pointer and release ownership.
593: device_type * release()
594: {
595: device_type * dev = m_dev;
596: m_dev = 0;
597: return dev;
598: }
599:
600: /// Replace the pointer.
601: /// Used to call dev->autodetect_open().
602: void replace(device_type * dev)
603: { m_dev = dev; }
604:
605: /// Return the pointer.
606: device_type * get() const
607: { return m_dev; }
608:
609: /// Pointer dereferencing.
610: device_type & operator*() const
611: { return *m_dev; }
612:
613: /// Pointer dereferencing.
614: device_type * operator->() const
615: { return m_dev; }
616:
617: /// For (ptr != 0) check.
618: operator bool() const
619: { return !!m_dev; }
620:
621: /// For (ptr == 0) check.
622: bool operator !() const
623: { return !m_dev; }
624:
625: private:
626: device_type * m_dev;
627: smart_device * m_base_dev;
628:
629: void fail() const
630: { throw std::logic_error("any_device_auto_ptr: wrong usage"); }
631:
632: // Prevent copy/assignment
633: any_device_auto_ptr(const any_device_auto_ptr<Dev> &);
634: void operator=(const any_device_auto_ptr<Dev> &);
635: };
636:
637: typedef any_device_auto_ptr<smart_device> smart_device_auto_ptr;
638: typedef any_device_auto_ptr<ata_device> ata_device_auto_ptr;
639: typedef any_device_auto_ptr<scsi_device> scsi_device_auto_ptr;
640:
641:
642: /////////////////////////////////////////////////////////////////////////////
643: // smart_device_list
644:
645: /// List of devices for DEVICESCAN
646: class smart_device_list
647: {
648: // Construction
649: public:
650: smart_device_list()
651: { }
652:
653: ~smart_device_list() throw()
654: {
655: for (unsigned i = 0; i < m_list.size(); i++)
656: delete m_list[i];
657: }
658:
659: // Attributes
660: unsigned size() const
661: { return m_list.size(); }
662:
663: // Operations
664: void clear()
665: {
666: for (unsigned i = 0; i < m_list.size(); i++)
667: delete m_list[i];
668: m_list.clear();
669: }
670:
671:
672: void push_back(smart_device * dev)
673: { m_list.push_back(dev); }
674:
675: void push_back(smart_device_auto_ptr & dev)
676: {
677: m_list.push_back(dev.get());
678: dev.release();
679: }
680:
681: smart_device * at(unsigned i)
682: { return m_list.at(i); }
683:
684: const smart_device * at(unsigned i) const
685: { return m_list.at(i); }
686:
687: smart_device * release(unsigned i)
688: {
689: smart_device * dev = m_list.at(i);
690: m_list[i] = 0;
691: return dev;
692: }
693:
694: // Implementation
695: private:
696: std::vector<smart_device *> m_list;
697:
698: // Prevent copy/assigment
699: smart_device_list(const smart_device_list &);
700: void operator=(const smart_device_list &);
701: };
702:
703:
704: /////////////////////////////////////////////////////////////////////////////
705: // smart_interface
706:
707: /// The platform interface abstraction
708: class smart_interface
709: {
710: public:
711: /// Initialize platform interface and register with smi().
712: /// Must be implemented by platform module and register interface with set()
713: static void init();
714:
715: smart_interface()
716: { }
717:
718: virtual ~smart_interface() throw()
719: { }
720:
721: /// Return info string about build host and/or OS version.
722: /// Default implementation returns SMARTMONTOOLS_BUILD_HOST.
723: virtual std::string get_os_version_str();
724:
725: /// Return valid args for device type option/directive.
726: /// Default implementation returns "ata, scsi, sat, usb*..."
727: /// concatenated with result from get_valid_custom_dev_types_str().
728: virtual std::string get_valid_dev_types_str();
729:
730: /// Return example string for program 'appname'.
731: /// Default implementation returns empty string.
732: /// For the migration of print_smartctl_examples(),
733: /// function is allowed to print examples to stdout.
734: /// TODO: Remove this hack.
735: virtual std::string get_app_examples(const char * appname);
736:
1.1.1.2 ! misho 737: /// Get microseconds since some unspecified starting point.
! 738: /// Used only for command duration measurements in debug outputs.
! 739: /// Returns -1 if unsupported.
! 740: /// Default implementation uses clock_gettime(), gettimeofday() or ftime().
! 741: virtual int64_t get_timer_usec();
! 742:
! 743: /// Disable/Enable system auto standby/sleep mode.
! 744: /// Return false if unsupported or if system is running
! 745: /// on battery.
! 746: /// Default implementation returns false.
! 747: virtual bool disable_system_auto_standby(bool disable);
! 748:
! 749:
1.1 misho 750: ///////////////////////////////////////////////
751: // Last error information
752:
753: /// Get last error info struct.
754: const smart_device::error_info & get_err() const
755: { return m_err; }
756: /// Get last error number.
757: int get_errno() const
758: { return m_err.no; }
759: /// Get last error message.
760: const char * get_errmsg() const
761: { return m_err.msg.c_str(); }
762:
763: /// Set last error number and message.
764: /// Printf()-like formatting is supported.
1.1.1.2 ! misho 765: /// Returns false always to allow use as a return expression.
! 766: bool set_err(int no, const char * msg, ...)
! 767: __attribute_format_printf(3, 4);
1.1 misho 768:
769: /// Set last error info struct.
1.1.1.2 ! misho 770: bool set_err(const smart_device::error_info & err)
! 771: { m_err = err; return false; }
1.1 misho 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).
1.1.1.2 ! misho 779: bool set_err(int no);
1.1 misho 780:
781: /// Set last error number and default message to any error_info.
782: /// Used by set_err(no).
1.1.1.2 ! misho 783: bool set_err_var(smart_device::error_info * err, int no);
1.1 misho 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:
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;
803:
804: protected:
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().
820: /// Default implementation returns empty string.
821: virtual std::string get_valid_custom_dev_types_str();
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:
828: public:
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:
843: protected:
844: /// Set interface to use, must be called from init().
845: static void set(smart_interface * intf)
846: { s_instance = intf; }
847:
848: // Implementation
849: private:
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
865: inline smart_interface * smi()
866: { return smart_interface::s_instance; }
867:
868: /////////////////////////////////////////////////////////////////////////////
869:
870: #endif // DEV_INTERFACE_H
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>