[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[cdi-devel] [PATCH 1/8] cdi/misc: Add CDI_UPCAST and endianness functions



From: Max Reitz <max@xxxxxxxxxx>

+ Type inheritance is a common pattern seen in CDI. The new CDI_UPCAST()
  macro makes conversion to superclasses safer and allows for multiple
  inheritance if the need arises.
+ Add some endianness conversion functions. Even though support for big
  endian platforms is nowhere in sight, endianness conversion is still a
  common operation which should not be implemented in the driver itself
  but provided by the CDI implementation.

Signed-off-by: Max Reitz <max@xxxxxxxxxx>
---
 include/cdi/misc.h | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)

diff --git a/include/cdi/misc.h b/include/cdi/misc.h
index a9f60b9..ab56e43 100644
--- a/include/cdi/misc.h
+++ b/include/cdi/misc.h
@@ -79,6 +79,64 @@ int cdi_ioports_free(uint16_t start, uint16_t count);
  */
 void cdi_sleep_ms(uint32_t ms);
 
+/**
+ * Casts @object (must be a pointer) to a pointer to an object of type @to which
+ * must be a baseclass of @object's type. @field is the entry in @to which
+ * contains @object.
+ *
+ * Example:
+ * struct cdi_driver *driver;
+ * struct cdi_storage_driver *storage_driver =
+ *     CDI_UPCAST(driver, drv, struct cdi_storage_driver);
+ */
+#define CDI_UPCAST(object, field, to) \
+    (to *)((uintptr_t)object - (uintptr_t)&((to *)0)->field)
+
+/**
+ * Functions for endianness conversion. Be aware that most if not all CDI
+ * drivers only support little endian machines as a host.
+ */
+
+static inline uint16_t cdi_be16_to_cpu(uint16_t x)
+{
+    return (x >> 8) | (x << 8);
+}
+
+static inline uint32_t cdi_be32_to_cpu(uint32_t x)
+{
+    return ((uint32_t)cdi_be16_to_cpu(x) << 16) | (uint32_t)cdi_be16_to_cpu(x >> 16);
+}
+
+static inline uint16_t cdi_cpu_to_be16(uint16_t x)
+{
+    return cdi_be16_to_cpu(x);
+}
+
+static inline uint32_t cdi_cpu_to_be32(uint32_t x)
+{
+    return cdi_be32_to_cpu(x);
+}
+
+static inline uint16_t cdi_le16_to_cpu(uint16_t x)
+{
+    return x;
+}
+
+static inline uint32_t cdi_le32_to_cpu(uint32_t x)
+{
+    return x;
+}
+
+static inline uint16_t cdi_cpu_to_le16(uint16_t x)
+{
+    return cdi_le16_to_cpu(x);
+}
+
+static inline uint32_t cdi_cpu_to_le32(uint32_t x)
+{
+    return cdi_le32_to_cpu(x);
+}
+
 #ifdef __cplusplus
 }; // extern "C"
 #endif
-- 
2.3.4