[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