summaryrefslogtreecommitdiffstats
path: root/dev_tunnelled.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dev_tunnelled.h93
1 files changed, 93 insertions, 0 deletions
diff --git a/dev_tunnelled.h b/dev_tunnelled.h
new file mode 100644
index 0000000..bacd318
--- /dev/null
+++ b/dev_tunnelled.h
@@ -0,0 +1,93 @@
+/*
+ * dev_tunnelled.h
+ *
+ * Home page of code is: https://www.smartmontools.org
+ *
+ * Copyright (C) 2008-21 Christian Franke
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef DEV_TUNNELLED_H
+#define DEV_TUNNELLED_H
+
+#define DEV_TUNNELLED_H_CVSID "$Id: dev_tunnelled.h 5198 2021-02-01 20:36:02Z chrfranke $"
+
+#include "dev_interface.h"
+
+/////////////////////////////////////////////////////////////////////////////
+// tunnelled_device_base
+
+/// Common functionality for all tunnelled_device classes.
+
+class tunnelled_device_base
+: virtual public /*implements*/ smart_device
+{
+protected:
+ explicit tunnelled_device_base(smart_device * tunnel_dev);
+
+public:
+ virtual ~tunnelled_device_base();
+
+ virtual bool is_open() const override;
+
+ virtual bool open() override;
+
+ virtual bool close() override;
+
+ virtual bool owns(const smart_device * dev) const override;
+
+ virtual void release(const smart_device * dev) override;
+
+private:
+ smart_device * m_tunnel_base_dev;
+};
+
+
+/////////////////////////////////////////////////////////////////////////////
+// tunnelled_device
+
+/// Implement a device by tunneling through another device
+
+template <class BaseDev, class TunnelDev>
+class tunnelled_device
+: public BaseDev,
+ public tunnelled_device_base
+{
+public:
+ typedef TunnelDev tunnel_device_type;
+
+protected:
+ explicit tunnelled_device(tunnel_device_type * tunnel_dev)
+ : smart_device(smart_device::never_called),
+ tunnelled_device_base(tunnel_dev),
+ m_tunnel_dev(tunnel_dev)
+ { }
+
+ // For nvme_device
+ explicit tunnelled_device(tunnel_device_type * tunnel_dev, unsigned nsid)
+ : smart_device(smart_device::never_called),
+ BaseDev(nsid),
+ tunnelled_device_base(tunnel_dev),
+ m_tunnel_dev(tunnel_dev)
+ { }
+
+public:
+ virtual void release(const smart_device * dev) override
+ {
+ if (m_tunnel_dev == dev)
+ m_tunnel_dev = 0;
+ tunnelled_device_base::release(dev);
+ }
+
+ tunnel_device_type * get_tunnel_dev()
+ { return m_tunnel_dev; }
+
+ const tunnel_device_type * get_tunnel_dev() const
+ { return m_tunnel_dev; }
+
+private:
+ tunnel_device_type * m_tunnel_dev;
+};
+
+#endif // DEV_TUNNELLED_H